<?php

namespace App\Filament\Pages;

use App\Enums\Currency;
use App\Enums\PaymentStatus;
use App\Enums\UserRole;
use App\Models\Sale;
use App\Models\SystemSetting;
use App\Models\User;
use Filament\Pages\Page;
use Livewire\Attributes\Url;

class CommissionsReportPage extends Page
{
    protected static ?string $navigationIcon  = 'heroicon-o-calculator';
    protected static ?string $navigationGroup = 'Reportes';
    protected static ?string $navigationLabel = 'Comisiones';
    protected static ?int    $navigationSort  = 12;
    protected static string  $view = 'filament.pages.commissions-report-page';

    #[Url(as: 'tab')]
    public string $activeTab = 'account';

    #[Url(as: 'desde')]
    public string $desde = '';

    #[Url(as: 'hasta')]
    public string $hasta = '';

    #[Url(as: 'preset')]
    public string $preset = 'month';

    public function mount(): void
    {
        if (! $this->desde || ! $this->hasta) {
            [$this->desde, $this->hasta] = $this->presetDates($this->preset);
        }
    }

    public function setPreset(string $preset): void
    {
        $this->preset = $preset;
        [$this->desde, $this->hasta] = $this->presetDates($preset);
    }

    public function setTab(string $tab): void
    {
        $this->activeTab = $tab;
    }

    private function presetDates(string $preset): array
    {
        return match ($preset) {
            'lastmonth' => [
                now()->subMonth()->startOfMonth()->toDateString(),
                now()->subMonth()->endOfMonth()->toDateString(),
            ],
            'months3' => [
                now()->subMonths(2)->startOfMonth()->toDateString(),
                now()->toDateString(),
            ],
            'year' => [
                now()->startOfYear()->toDateString(),
                now()->toDateString(),
            ],
            default => [
                now()->startOfMonth()->toDateString(),
                now()->toDateString(),
            ],
        };
    }

    // ── Reporte Account Manager ──────────────────────────────────────────────
    // Comisión sobre proyectos CON al menos un pago en el período

    public function getAccountReportData(): array
    {
        $settings = SystemSetting::current();
        $pct      = (float) $settings->account_commission_pct;
        $rate     = (float) $settings->exchange_rate_usd_bob;

        $desde = $this->desde ?: now()->startOfMonth()->toDateString();
        $hasta = $this->hasta ?: now()->toDateString();

        // Ventas que tienen pagos en el período
        $sales = Sale::with(['client', 'payments' => function ($q) use ($desde, $hasta) {
                $q->whereBetween('payment_date', [$desde, $hasta]);
            }])
            ->whereHas('payments', fn ($q) => $q->whereBetween('payment_date', [$desde, $hasta]))
            ->get();

        $rows = $sales->map(function (Sale $sale) use ($pct, $rate) {
            $cobradoUsd = $sale->payments
                ->where('currency', Currency::USD)
                ->sum(fn ($p) => (float) $p->amount);
            $cobradoBob = $sale->payments
                ->where('currency', Currency::BOB)
                ->sum(fn ($p) => (float) $p->amount);

            $cobradoEnBs   = round(($cobradoUsd * $rate) + $cobradoBob, 2);
            $comisionBs    = round($cobradoEnBs * $pct / 100, 2);

            return [
                'client'        => $sale->client?->name ?? '—',
                'title'         => $sale->title,
                'cobrado_usd'   => $cobradoUsd,
                'cobrado_bob'   => $cobradoBob,
                'cobrado_bs'    => $cobradoEnBs,
                'pct'           => $pct,
                'comision_bs'   => $comisionBs,
                'sale_id'       => $sale->id,
            ];
        })->sortBy('client')->values();

        $totalComisionBs = $rows->sum('comision_bs');

        // Account manager por defecto: Tania Romero (gestor_cuenta) o el primero disponible
        $accountManager = User::where('role', UserRole::GestorCuenta->value)
            ->where('email', 'tania@nuna.tech')
            ->first()
            ?? User::where('role', UserRole::GestorCuenta->value)->first();

        return [
            'rows'              => $rows,
            'total_comision_bs' => $totalComisionBs,
            'pct'               => $pct,
            'account_manager'   => $accountManager,
            'rate'              => $rate,
            'desde'             => $desde,
            'hasta'             => $hasta,
        ];
    }

    // ── Reporte Vendedor ─────────────────────────────────────────────────────
    // Comisión sobre ventas globales, con indicador de si el cliente pagó

    public function getSalesRepReportData(): array
    {
        $settings    = SystemSetting::current();
        $defaultPct  = (float) $settings->sales_commission_pct;
        $rate        = (float) $settings->exchange_rate_usd_bob;

        $desde = $this->desde ?: now()->startOfMonth()->toDateString();
        $hasta = $this->hasta ?: now()->toDateString();

        $sellers = User::where('role', UserRole::Vendedor->value)->get();

        $data = [];

        foreach ($sellers as $seller) {
            $sales = Sale::with('client', 'payments')
                ->where('seller_user_id', $seller->id)
                ->whereBetween('sale_date', [$desde, $hasta])
                ->get();

            $rows = $sales->map(function (Sale $sale) use ($defaultPct, $rate) {
                $pct = $sale->sales_commission_pct !== null
                    ? (float) $sale->sales_commission_pct
                    : $defaultPct;

                $grossBs    = $sale->currency === Currency::USD
                    ? round((float) $sale->gross_amount * $rate, 2)
                    : (float) $sale->gross_amount;
                $comisionBs = round($grossBs * $pct / 100, 2);

                $cobradoUsd = $sale->payments
                    ->where('currency', Currency::USD)
                    ->sum(fn ($p) => (float) $p->amount);
                $cobradoBob = $sale->payments
                    ->where('currency', Currency::BOB)
                    ->sum(fn ($p) => (float) $p->amount);

                return [
                    'client'        => $sale->client?->name ?? '—',
                    'title'         => $sale->title,
                    'sale_date'     => $sale->sale_date->format('d/m/Y'),
                    'gross_usd'     => $sale->currency === Currency::USD ? (float) $sale->gross_amount : null,
                    'gross_bob'     => $sale->currency === Currency::BOB ? (float) $sale->gross_amount : null,
                    'gross_bs'      => $grossBs,
                    'pct'           => $pct,
                    'comision_bs'   => $comisionBs,
                    'pagado'        => $sale->payment_status === PaymentStatus::Paid,
                    'parcial'       => $sale->payment_status === PaymentStatus::Partial,
                    'cobrado_usd'   => $cobradoUsd,
                    'cobrado_bob'   => $cobradoBob,
                    'status_label'  => $sale->payment_status?->label() ?? '—',
                    'sale_id'       => $sale->id,
                ];
            })->sortBy('sale_date')->values();

            $totalGrossBs    = $rows->sum('gross_bs');
            $totalComisionBs = $rows->sum('comision_bs');
            $cobradosCount   = $rows->where('pagado', true)->count();

            $data[] = [
                'seller'            => $seller,
                'rows'              => $rows,
                'total_gross_bs'    => $totalGrossBs,
                'total_comision_bs' => $totalComisionBs,
                'cobrados_count'    => $cobradosCount,
                'total_count'       => $rows->count(),
            ];
        }

        return [
            'sellers_data' => $data,
            'default_pct'  => $defaultPct,
            'rate'         => $rate,
            'desde'        => $desde,
            'hasta'        => $hasta,
        ];
    }

    public function getTitle(): string
    {
        return 'Reporte de Comisiones';
    }
}
