<?php

declare(strict_types=1);

namespace App\Controllers;

use App\Core\Controller;
use App\Core\Request;
use App\Services\CommissionService;
use App\Services\InvoiceService;
use App\Services\WithdrawalService;

class FinanceController extends Controller
{
    private InvoiceService $invoices;
    private CommissionService $commissions;
    private WithdrawalService $withdrawals;

    public function __construct()
    {
        $this->invoices = new InvoiceService();
        $this->commissions = new CommissionService();
        $this->withdrawals = new WithdrawalService();
    }

    public function studentInvoices(): string
    {
        require_role('student');

        return $this->view('finance/invoices/student', [
            'title' => 'Meus recibos',
            'invoices' => $this->invoices->invoicesForStudent((int) current_user()['id']),
        ]);
    }

    public function invoice(Request $request): string
    {
        require_auth();
        $invoice = $this->invoices->find((int) $request->input('id'));

        if (!$invoice || (!$this->canSeeInvoice($invoice))) {
            flash('error', 'Recibo nao encontrado.');
            app()->response()->redirect('/dashboard');
        }

        return $this->view('finance/invoices/show', [
            'title' => 'Recibo ' . $invoice['invoice_number'],
            'invoice' => $invoice,
        ]);
    }

    public function adminInvoices(Request $request): string
    {
        require_role('admin');

        $filters = [
            'search' => (string) $request->input('search', ''),
        ];

        return $this->view('admin/finance/invoices', [
            'title' => 'Recibos',
            'invoices' => $this->invoices->all($filters),
            'filters' => $filters,
        ]);
    }

    public function adminCommissions(): string
    {
        require_role('admin');
        $items = $this->commissions->all();

        return $this->view('admin/finance/commissions', [
            'title' => 'Comissoes',
            'commissions' => $items,
            'totals' => $this->commissions->totals($items),
        ]);
    }

    public function adminWithdrawals(Request $request): string
    {
        require_role('admin');

        $filters = [
            'status' => (string) $request->input('status', ''),
            'search' => (string) $request->input('search', ''),
        ];

        return $this->view('admin/finance/withdrawals', [
            'title' => 'Levantamentos',
            'withdrawals' => $this->withdrawals->all($filters),
            'filters' => $filters,
            'withdrawalsService' => $this->withdrawals,
        ]);
    }

    public function updateWithdrawal(Request $request): void
    {
        require_role('admin');

        if (!verify_csrf((string) $request->post('_csrf_token', ''))) {
            flash('error', 'Sessao expirada. Tente novamente.');
            app()->response()->back();
        }

        $result = $this->withdrawals->changeStatus(
            (int) $request->post('withdrawal_id'),
            (string) $request->post('status'),
            current_user(),
            (string) $request->post('admin_note', '')
        );

        flash($result['ok'] ? 'success' : 'error', $result['ok'] ? 'Levantamento actualizado.' : $result['error']);
        app()->response()->back();
    }

    public function earnings(): string
    {
        require_auth();
        $user = current_user();

        if (!in_array($user['role'] ?? '', ['admin', 'instructor', 'institution'], true)) {
            flash('error', 'Nao tem permissao para ver ganhos.');
            app()->response()->redirect('/dashboard');
        }

        $sellerType = match ($user['role']) {
            'institution' => 'institution',
            'admin' => 'platform',
            default => 'instructor',
        };

        $items = $this->commissions->all([
            'seller_type' => $sellerType,
            'seller_id' => (int) $user['id'],
        ]);

        return $this->view('finance/earnings', [
            'title' => 'Ganhos',
            'commissions' => $items,
            'totals' => $this->commissions->totals($items),
            'wallet' => $this->withdrawals->wallet($sellerType, (int) $user['id']),
            'withdrawals' => $this->withdrawals->forSeller($sellerType, (int) $user['id']),
            'withdrawalsService' => $this->withdrawals,
        ]);
    }

    public function requestWithdrawal(Request $request): void
    {
        require_auth();
        $user = current_user();

        if (!in_array($user['role'] ?? '', ['admin', 'instructor', 'institution'], true)) {
            flash('error', 'Nao tem permissao para pedir levantamento.');
            app()->response()->redirect('/dashboard');
        }

        if (!verify_csrf((string) $request->post('_csrf_token', ''))) {
            flash('error', 'Sessao expirada. Tente novamente.');
            app()->response()->back();
        }

        $result = $this->withdrawals->request($request->all(), $user);
        flash($result['ok'] ? 'success' : 'error', $result['ok'] ? 'Pedido de levantamento enviado.' : $result['error']);
        app()->response()->back();
    }

    private function canSeeInvoice(array $invoice): bool
    {
        if (has_role('admin')) {
            return true;
        }

        return has_role('student') && (int) ($invoice['student_id'] ?? 0) === (int) current_user()['id'];
    }
}
