<?php

namespace App\Filament\Pages;

use App\Enums\Currency;
use App\Enums\SaleOrigin;
use App\Models\Sale;
use App\Models\SystemSetting;
use Carbon\Carbon;
use Filament\Pages\Page;
use Livewire\Attributes\Url;

class SalesReportPage extends Page
{
    protected static ?string $navigationIcon  = 'heroicon-o-chart-bar';
    protected static ?string $navigationGroup = 'Reportes';
    protected static ?string $navigationLabel = 'Reporte de Ventas';
    protected static ?int    $navigationSort  = 10;
    protected static string  $view = 'filament.pages.sales-report-page';

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

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

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

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

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

    public static 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(),
            ],
            default => [
                now()->startOfMonth()->toDateString(),
                now()->toDateString(),
            ],
        };
    }

    // ── Datos del reporte ────────────────────────────────────────────────────

    public function getReportData(): array
    {
        $rate  = (float) SystemSetting::current()->exchange_rate_usd_bob;
        $desde = $this->desde ?: now()->startOfMonth()->toDateString();
        $hasta = $this->hasta ?: now()->toDateString();

        $sales = Sale::with('client')
            ->whereBetween('sale_date', [$desde, $hasta])
            ->orderBy('origin')
            ->orderBy('sale_date', 'desc')
            ->get();

        $origins = [
            SaleOrigin::Upwork->value => ['label' => 'Upwork', 'icon' => '🔗', 'sales' => collect()],
            SaleOrigin::Manual->value => ['label' => 'Manual / Local', 'icon' => '🏠', 'sales' => collect()],
        ];

        foreach ($sales as $sale) {
            $key = $sale->origin?->value ?? SaleOrigin::Manual->value;
            if (! isset($origins[$key])) {
                $origins[$key] = ['label' => $key, 'icon' => '📋', 'sales' => collect()];
            }
            $origins[$key]['sales']->push($sale);
        }

        // Calcular totales por origen
        foreach ($origins as $key => &$group) {
            $group['totals'] = $this->calcTotals($group['sales'], $rate);
        }

        // Grand total
        $grandTotal = $this->calcTotals($sales, $rate);

        return [
            'origins'    => array_filter($origins, fn ($g) => $g['sales']->isNotEmpty()),
            'grandTotal' => $grandTotal,
            'rate'       => $rate,
            'desde'      => $desde,
            'hasta'      => $hasta,
        ];
    }

    private function calcTotals($sales, float $rate): array
    {
        $usd = $sales->filter(fn ($s) => $s->currency === Currency::USD);
        $bob = $sales->filter(fn ($s) => $s->currency === Currency::BOB);

        $brutUsd  = $usd->sum(fn ($s) => (float) $s->gross_amount);
        $feeUsd   = $usd->sum(fn ($s) => (float) $s->platform_fee);
        $netUsd   = $usd->sum(fn ($s) => $s->net_expected);

        $brutBob  = $bob->sum(fn ($s) => (float) $s->gross_amount);
        $feeBob   = $bob->sum(fn ($s) => (float) $s->platform_fee);
        $netBob   = $bob->sum(fn ($s) => $s->net_expected);

        $totalBs  = round(($netUsd * $rate) + $netBob, 2);

        return [
            'count'   => $sales->count(),
            'usd'     => ['bruto' => $brutUsd, 'fee' => $feeUsd, 'neto' => $netUsd],
            'bob'     => ['bruto' => $brutBob, 'fee' => $feeBob, 'neto' => $netBob],
            'totalBs' => $totalBs,
        ];
    }

    public function getExportUrl(): string
    {
        return route('export.sales', [
            'date_from' => $this->desde,
            'date_to'   => $this->hasta,
        ]);
    }

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