<?php

namespace App\Filament\Pages;

use App\Models\Order;
use App\Models\PurchaseOrder;
use App\Models\Supplier;
use App\Models\User;
use Filament\Actions\Action;
use Filament\Notifications\Notification;
use Filament\Pages\Page;
use Illuminate\Support\Carbon;
use Symfony\Component\HttpFoundation\StreamedResponse;

class FinancialReport extends Page
{
    protected static string | \BackedEnum | null $navigationIcon = 'heroicon-o-chart-bar';

    protected static string | \UnitEnum | null $navigationGroup = 'التقارير';

    protected static ?string $navigationLabel = 'التقرير المالي';

    protected static ?string $title = 'التقرير المالي الشامل';

    protected static ?int $navigationSort = 8;

    public ?string $startDate = null;

    public ?string $endDate = null;

    public ?int $supplierId = null;

    public ?int $agentId = null;

    protected string $view = 'filament.pages.financial-report';

    public function mount(): void
    {
        $this->startDate = Carbon::today()->subDays(29)->format('Y-m-d');
        $this->endDate = Carbon::today()->format('Y-m-d');
    }

    public static function canAccess(): bool
    {
        return auth()->user()?->hasPermissionTo('view_financial_reports') ?? false;
    }

    protected function getHeaderActions(): array
    {
        return [
            Action::make('exportCsv')
                ->label('تصدير Excel (CSV)')
                ->icon('heroicon-o-arrow-down-tray')
                ->color('gray')
                ->action(fn () => $this->exportCsv()),
            Action::make('exportPdf')
                ->label('تصدير PDF')
                ->icon('heroicon-o-document-arrow-down')
                ->color('gray')
                ->url(fn () => route('admin.financial-report.export-pdf', [
                    'startDate' => $this->startDate,
                    'endDate' => $this->endDate,
                    'supplierId' => $this->supplierId,
                    'agentId' => $this->agentId,
                ]))
                ->openUrlInNewTab(),
        ];
    }

    public function applyFilters(): void
    {
        $this->validate([
            'startDate' => 'required|date',
            'endDate' => 'required|date|after_or_equal:startDate',
        ]);
        Notification::make()
            ->title('تم تطبيق الفلاتر')
            ->success()
            ->send();
    }

    protected function getBaseQuery()
    {
        $start = $this->startDate ? $this->startDate . ' 00:00:00' : Carbon::today()->subDays(29)->format('Y-m-d 00:00:00');
        $end = $this->endDate ? $this->endDate . ' 23:59:59' : Carbon::today()->format('Y-m-d 23:59:59');

        $q = Order::query()->whereBetween('created_at', [$start, $end]);

        if ($this->supplierId) {
            $q->whereHas('items.variant', fn ($sq) => $sq->where('default_supplier_id', $this->supplierId));
        }
        if ($this->agentId) {
            $q->where('user_id', $this->agentId);
        }

        return $q;
    }

    public function getReportData(): array
    {
        $baseQuery = $this->getBaseQuery();

        $revenueSummary = (clone $baseQuery)
            ->selectRaw("
                SUM(CASE WHEN status != 'returned' THEN total ELSE 0 END) as total_revenue,
                SUM(CASE WHEN status != 'returned' THEN total_profit ELSE 0 END) as total_profit,
                SUM(CASE WHEN status != 'returned' THEN COALESCE(shipping_cost, 0) ELSE 0 END) as total_shipping,
                SUM(CASE WHEN status != 'returned' THEN COALESCE(payment_fee, 0) ELSE 0 END) as total_payment_fees,
                SUM(CASE WHEN status != 'returned' THEN discount_from_points ELSE 0 END) as total_points_discount,
                SUM(CASE WHEN status = 'returned' THEN total ELSE 0 END) as returned_value,
                COUNT(CASE WHEN status = 'returned' THEN 1 END) as returned_count
            ")
            ->first();

        $totalRevenue = (float) ($revenueSummary->total_revenue ?? 0);
        $totalProfit = (float) ($revenueSummary->total_profit ?? 0);
        $totalShipping = (float) ($revenueSummary->total_shipping ?? 0);
        $totalPaymentFees = (float) ($revenueSummary->total_payment_fees ?? 0);
        $totalPointsDiscount = (float) ($revenueSummary->total_points_discount ?? 0);

        $supplierQ = Supplier::where('is_active', true);
        if ($this->supplierId) {
            $supplierQ->where('id', $this->supplierId);
        }
        $supplierBalances = $supplierQ->select('id', 'name', 'current_balance')->orderByDesc('current_balance')->get();
        $totalSupplierDebt = (float) $supplierBalances->sum('current_balance');

        $purchaseQ = PurchaseOrder::whereIn('status', ['confirmed', 'received']);
        if ($this->supplierId) {
            $purchaseQ->where('supplier_id', $this->supplierId);
        }
        $totalPurchaseCosts = (float) $purchaseQ->sum('total_cost');

        $netProfitEstimate = $totalProfit - $totalSupplierDebt;

        $lineChartData = $this->getLineChartData();
        $pieChartData = $this->getPieChartData();
        $recentOrders = $this->getRecentOrders();

        return [
            'totalRevenue' => $totalRevenue,
            'totalProfit' => $totalProfit,
            'totalShippingAndFees' => $totalShipping + $totalPaymentFees,
            'totalSupplierDebt' => $totalSupplierDebt,
            'supplierBalances' => $supplierBalances,
            'netProfitEstimate' => $netProfitEstimate,
            'totalPurchaseCosts' => $totalPurchaseCosts,
            'returnedOrders' => (int) ($revenueSummary->returned_count ?? 0),
            'returnedValue' => (float) ($revenueSummary->returned_value ?? 0),
            'totalPointsDiscount' => $totalPointsDiscount,
            'lineChartData' => $lineChartData,
            'pieChartData' => $pieChartData,
            'recentOrders' => $recentOrders,
            'statusLabels' => Order::getStatusLabels(),
        ];
    }

    protected function getLineChartData(): array
    {
        $start = Carbon::parse($this->startDate)->startOfDay();
        $end = Carbon::parse($this->endDate)->endOfDay();
        $days = max(1, $start->diffInDays($end) + 1);

        $dailyData = (clone $this->getBaseQuery())
            ->whereNotIn('status', [Order::STATUS_RETURNED])
            ->selectRaw("DATE(created_at) as day, COALESCE(SUM(total), 0) as revenue")
            ->groupByRaw('DATE(created_at)')
            ->pluck('revenue', 'day')
            ->toArray();

        $labels = [];
        $data = [];
        for ($i = 0; $i < $days; $i++) {
            $day = $start->copy()->addDays($i)->format('Y-m-d');
            $labels[] = Carbon::parse($day)->format('m/d');
            $data[] = (float) ($dailyData[$day] ?? 0);
        }

        return ['labels' => $labels, 'data' => $data];
    }

    protected function getPieChartData(): array
    {
        $govData = (clone $this->getBaseQuery())
            ->whereNotIn('status', [Order::STATUS_RETURNED])
            ->whereNotNull('shipping_governorate')
            ->where('shipping_governorate', '!=', '')
            ->selectRaw('shipping_governorate as gov, SUM(total) as total_value')
            ->groupBy('shipping_governorate')
            ->orderByDesc('total_value')
            ->limit(10)
            ->get();

        $labels = $govData->pluck('gov')->toArray();
        $data = $govData->pluck('total_value')->map(fn ($v) => (float) $v)->toArray();
        $colors = ['#10b981', '#3b82f6', '#f59e0b', '#ef4444', '#8b5cf6', '#06b6d4', '#ec4899', '#84cc16', '#f97316', '#14b8a6'];

        return ['labels' => $labels, 'data' => $data, 'colors' => array_slice($colors, 0, count($labels))];
    }

    protected function getRecentOrders()
    {
        return (clone $this->getBaseQuery())
            ->with(['user'])
            ->orderByDesc('created_at')
            ->limit(15)
            ->get();
    }

    public function exportCsv(): StreamedResponse
    {
        $data = $this->getReportData();
        $orders = $this->getRecentOrders();

        return response()->streamDownload(function () use ($data, $orders) {
            $handle = fopen('php://output', 'w');
            fprintf($handle, chr(0xEF) . chr(0xBB) . chr(0xBF)); // UTF-8 BOM
            fputcsv($handle, ['التقرير المالي', Carbon::parse($this->startDate)->format('Y-m-d'), 'إلى', Carbon::parse($this->endDate)->format('Y-m-d')]);
            fputcsv($handle, []);
            fputcsv($handle, ['إجمالي الإيرادات', number_format($data['totalRevenue'], 2) . ' EGP']);
            fputcsv($handle, ['الشحن ورسوم الدفع', number_format($data['totalShippingAndFees'], 2) . ' EGP']);
            fputcsv($handle, ['مديونية الموردين', number_format($data['totalSupplierDebt'], 2) . ' EGP']);
            fputcsv($handle, ['صافي الربح التقريبي', number_format($data['netProfitEstimate'], 2) . ' EGP']);
            fputcsv($handle, []);
            fputcsv($handle, ['أحدث المعاملات']);
            fputcsv($handle, ['#', 'التاريخ', 'التاجر', 'الحالة', 'الإجمالي']);

            foreach ($orders as $i => $o) {
                fputcsv($handle, [
                    $i + 1,
                    $o->created_at->format('Y-m-d H:i'),
                    $o->user?->name ?? '-',
                    $data['statusLabels'][$o->status] ?? $o->status,
                    number_format($o->total, 2) . ' EGP',
                ]);
            }
            fclose($handle);
        }, 'financial-report-' . now()->format('Y-m-d-His') . '.csv', [
            'Content-Type' => 'text/csv; charset=UTF-8',
        ]);
    }
}
