<?php

namespace App\Filament\Pages;

use App\Exports\OrdersReportExport;
use App\Exports\SalesReportExport;
use App\Models\Client;
use App\Models\Order;
use App\Models\Technician;
use Barryvdh\DomPDF\Facade\Pdf;
use Filament\Actions\Action;
use Filament\Forms\Components\DatePicker;
use Filament\Forms\Components\Select;
use Filament\Notifications\Notification;
use Filament\Pages\Page;
use Filament\Schemas\Components\Actions;
use Filament\Schemas\Components\EmbeddedSchema;
use Filament\Schemas\Components\Form;
use Filament\Schemas\Components\Section;
use Filament\Schemas\Concerns\InteractsWithSchemas;
use Filament\Schemas\Contracts\HasSchemas;
use Filament\Schemas\Schema;
use Illuminate\Support\Carbon;
use Maatwebsite\Excel\Facades\Excel;

class FinancialReports extends Page implements HasSchemas
{
    use InteractsWithSchemas;

    protected static string | \BackedEnum | null $navigationIcon = 'heroicon-o-document-chart-bar';

    protected static ?string $navigationLabel = 'التقارير الحسابية';

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

    protected static ?int $navigationSort = 1;

    protected static bool $shouldRegisterNavigation = false;

    public ?string $report_type = null;
    public ?string $start_date = null;
    public ?string $end_date = null;
    public ?string $status = null;
    public ?int $client_id = null;
    public ?int $technician_id = null;

    public function mount(): void
    {
        $this->form->fill([
            'report_type' => 'orders',
            'start_date' => Carbon::now()->startOfMonth()->format('Y-m-d'),
            'end_date' => Carbon::now()->format('Y-m-d'),
        ]);
    }

    public function form(Schema $schema): Schema
    {
        return $schema
            ->components([
                Section::make('إعدادات التقرير')
                    ->description('اختر نوع التقرير والفلاتر المطلوبة')
                    ->icon('heroicon-o-funnel')
                    ->components([
                        Select::make('report_type')
                            ->label('نوع التقرير')
                            ->options([
                                'orders' => 'تقرير الطلبات',
                                'sales' => 'تقرير المبيعات',
                                'clients' => 'تقرير العملاء',
                                'technicians' => 'تقرير الفنيين',
                            ])
                            ->required()
                            ->default('orders')
                            ->live()
                            ->native(false)
                            ->columnSpanFull(),
                        DatePicker::make('start_date')
                            ->label('من تاريخ')
                            ->required()
                            ->native(false)
                            ->default(Carbon::now()->startOfMonth())
                            ->columnSpan(1),
                        DatePicker::make('end_date')
                            ->label('إلى تاريخ')
                            ->required()
                            ->native(false)
                            ->default(Carbon::now())
                            ->columnSpan(1),
                        Select::make('status')
                            ->label('حالة الطلب')
                            ->options([
                                'pending' => 'قيد الانتظار',
                                'confirmed' => 'مؤكد',
                                'in_progress' => 'قيد التنفيذ',
                                'completed' => 'مكتمل',
                                'cancelled' => 'ملغي',
                            ])
                            ->visible(fn () => in_array($this->report_type, ['orders', 'sales']))
                            ->native(false)
                            ->columnSpan(1),
                        Select::make('client_id')
                            ->label('العميل')
                            ->options(Client::pluck('name', 'id'))
                            ->searchable()
                            ->preload()
                            ->visible(fn () => in_array($this->report_type, ['orders', 'sales', 'clients']))
                            ->columnSpan(1),
                        Select::make('technician_id')
                            ->label('الفني')
                            ->options(Technician::pluck('name', 'id'))
                            ->searchable()
                            ->preload()
                            ->visible(fn () => in_array($this->report_type, ['orders', 'sales', 'technicians']))
                            ->columnSpan(1),
                    ])->columns(2),
            ]);
    }

    public function content(Schema $schema): Schema
    {
        return $schema
            ->components([
                Form::make([EmbeddedSchema::make('form')])
                    ->id('form')
                    ->footer([
                        Actions::make($this->getFormActions())
                            ->alignment('end')
                            ->key('form-actions'),
                    ]),
            ]);
    }

    protected function getFormActions(): array
    {
        return [
            Action::make('export_excel')
                ->label('تصدير Excel')
                ->icon('heroicon-o-arrow-down-tray')
                ->color('success')
                ->action('exportExcel'),
            Action::make('export_pdf')
                ->label('تصدير PDF')
                ->icon('heroicon-o-document-arrow-down')
                ->color('danger')
                ->action('exportPdf'),
        ];
    }

    public function exportExcel(): \Symfony\Component\HttpFoundation\BinaryFileResponse
    {
        $data = $this->form->getState();
        $orders = $this->getFilteredOrders($data);

        $filename = $this->getReportFilename($data['report_type'], 'xlsx');

        switch ($data['report_type']) {
            case 'orders':
                return Excel::download(new OrdersReportExport($orders), $filename);
            case 'sales':
                return Excel::download(new SalesReportExport($orders), $filename);
            case 'clients':
                return $this->exportClientsExcel($data);
            case 'technicians':
                return $this->exportTechniciansExcel($data);
            default:
                Notification::make()
                    ->title('خطأ')
                    ->body('نوع التقرير غير صحيح')
                    ->danger()
                    ->send();
                return redirect()->back();
        }
    }

    public function exportPdf()
    {
        $data = $this->form->getState();
        $orders = $this->getFilteredOrders($data);

        $filename = $this->getReportFilename($data['report_type'], 'pdf');

        switch ($data['report_type']) {
            case 'orders':
                return $this->exportOrdersPdf($orders, $data);
            case 'sales':
                return $this->exportSalesPdf($orders, $data);
            case 'clients':
                return $this->exportClientsPdf($data);
            case 'technicians':
                return $this->exportTechniciansPdf($data);
            default:
                Notification::make()
                    ->title('خطأ')
                    ->body('نوع التقرير غير صحيح')
                    ->danger()
                    ->send();
                return redirect()->back();
        }
    }

    protected function getFilteredOrders(array $data)
    {
        $query = Order::with(['client', 'service', 'technician']);

        if ($data['start_date']) {
            $query->whereDate('created_at', '>=', $data['start_date']);
        }

        if ($data['end_date']) {
            $query->whereDate('created_at', '<=', $data['end_date']);
        }

        if (!empty($data['status'])) {
            $query->where('status', $data['status']);
        }

        if (!empty($data['client_id'])) {
            $query->where('client_id', $data['client_id']);
        }

        if (!empty($data['technician_id'])) {
            $query->where('technician_id', $data['technician_id']);
        }

        return $query->get();
    }

    protected function getReportFilename(string $type, string $extension): string
    {
        $typeNames = [
            'orders' => 'الطلبات',
            'sales' => 'المبيعات',
            'clients' => 'العملاء',
            'technicians' => 'الفنيين',
        ];

        $date = Carbon::now()->format('Y-m-d');
        return $typeNames[$type] . '-' . $date . '.' . $extension;
    }

    protected function exportClientsExcel($data)
    {
        $query = Client::query();

        if ($data['start_date']) {
            $query->whereDate('created_at', '>=', $data['start_date']);
        }

        if ($data['end_date']) {
            $query->whereDate('created_at', '<=', $data['end_date']);
        }

        if (!empty($data['client_id'])) {
            $query->where('id', $data['client_id']);
        }

        $clients = $query->get();

        return Excel::download(new \App\Exports\ClientsExport($clients), $this->getReportFilename('clients', 'xlsx'));
    }

    protected function exportTechniciansExcel($data)
    {
        $query = Technician::withCount('orders');

        if ($data['start_date']) {
            $query->whereHas('orders', function ($q) use ($data) {
                $q->whereDate('created_at', '>=', $data['start_date']);
            });
        }

        if ($data['end_date']) {
            $query->whereHas('orders', function ($q) use ($data) {
                $q->whereDate('created_at', '<=', $data['end_date']);
            });
        }

        if (!empty($data['technician_id'])) {
            $query->where('id', $data['technician_id']);
        }

        $technicians = $query->get();

        // Create a simple export for technicians
        $export = new class($technicians) implements \Maatwebsite\Excel\Concerns\FromCollection, \Maatwebsite\Excel\Concerns\WithHeadings, \Maatwebsite\Excel\Concerns\WithMapping {
            protected $technicians;

            public function __construct($technicians)
            {
                $this->technicians = $technicians;
            }

            public function collection()
            {
                return $this->technicians;
            }

            public function headings(): array
            {
                return ['الاسم', 'البريد الإلكتروني', 'رقم الهاتف', 'عدد الطلبات', 'تاريخ الإنشاء'];
            }

            public function map($technician): array
            {
                return [
                    $technician->name,
                    $technician->email,
                    $technician->phone,
                    $technician->orders_count ?? 0,
                    $technician->created_at->format('Y-m-d'),
                ];
            }
        };

        return Excel::download($export, $this->getReportFilename('technicians', 'xlsx'));
    }

    protected function exportOrdersPdf($orders, $data)
    {
        $pdf = Pdf::loadView('reports.orders', [
            'orders' => $orders,
            'data' => $data,
            'title' => 'تقرير الطلبات',
            'totalFees' => $orders->sum('fee'),
            'totalPrice' => $orders->sum('price'),
            'totalCommission' => $orders->sum('technician_commission'),
            'totalDiscount' => $orders->sum('discount'),
            'totalAmount' => $orders->sum('total'),
        ])->setPaper('a4', 'landscape');

        return $pdf->download($this->getReportFilename('orders', 'pdf'));
    }

    protected function exportSalesPdf($orders, $data)
    {
        $totalSales = $orders->sum('total');
        $totalOrders = $orders->count();

        $pdf = Pdf::loadView('reports.sales', [
            'orders' => $orders,
            'data' => $data,
            'totalSales' => $totalSales,
            'totalOrders' => $totalOrders,
            'title' => 'تقرير المبيعات',
        ])->setPaper('a4', 'landscape');

        return $pdf->download($this->getReportFilename('sales', 'pdf'));
    }

    protected function exportClientsPdf($data)
    {
        $query = Client::withCount('orders');

        if ($data['start_date']) {
            $query->whereDate('created_at', '>=', $data['start_date']);
        }

        if ($data['end_date']) {
            $query->whereDate('created_at', '<=', $data['end_date']);
        }

        if (!empty($data['client_id'])) {
            $query->where('id', $data['client_id']);
        }

        $clients = $query->get();

        $pdf = Pdf::loadView('reports.clients', [
            'clients' => $clients,
            'data' => $data,
            'title' => 'تقرير العملاء',
        ])->setPaper('a4', 'landscape');

        return $pdf->download($this->getReportFilename('clients', 'pdf'));
    }

    protected function exportTechniciansPdf($data)
    {
        $query = Technician::with('service')->withCount('orders')
            ->withSum(['orders as completed_total' => function ($q) {
                $q->where('status', 'completed');
            }], 'total')
            ->withSum(['orders as completed_fee' => function ($q) {
                $q->where('status', 'completed');
            }], 'fee')
            ->withSum(['orders as completed_price' => function ($q) {
                $q->where('status', 'completed');
            }], 'price')
            ->withSum(['orders as completed_commission' => function ($q) {
                $q->where('status', 'completed');
            }], 'technician_commission');

        if ($data['start_date']) {
            $query->whereHas('orders', function ($q) use ($data) {
                $q->whereDate('created_at', '>=', $data['start_date']);
            });
        }

        if ($data['end_date']) {
            $query->whereHas('orders', function ($q) use ($data) {
                $q->whereDate('created_at', '<=', $data['end_date']);
            });
        }

        if (!empty($data['technician_id'])) {
            $query->where('id', $data['technician_id']);
        }

        $technicians = $query->get();

        $pdf = Pdf::loadView('reports.technicians', [
            'technicians' => $technicians,
            'data' => $data,
            'title' => 'تقرير الفنيين',
        ])->setPaper('a4', 'landscape');

        return $pdf->download($this->getReportFilename('technicians', 'pdf'));
    }
}
