<?php

namespace App\Filament\Pages;

use Carbon\Carbon;
use App\Models\Sale;
use App\Models\Customer;
use Filament\Pages\Page;
use App\Models\CustomerPayment;
use Illuminate\Contracts\View\View;
use Filament\Forms\Contracts\HasForms;
use Filament\Schemas\Components\Section;
use Filament\Forms\Components\DatePicker;
use Filament\Forms\Concerns\InteractsWithForms;
use Filament\Schemas\Schema;
use App\Exports\AllCustomersStatementExport;
use Maatwebsite\Excel\Facades\Excel;
use Mpdf\Mpdf;
use BezhanSalleh\FilamentShield\Traits\HasPageShield;
use Filament\Support\Icons\Heroicon;

class AllCustomersStatementReport extends Page implements HasForms
{
    use InteractsWithForms;
    use HasPageShield;

    protected string $view = 'filament.pages.all-customers-statement-report';

    public ?array $data = [];
    public ?array $report_data = null;
    public string $search = '';

    protected static string|\BackedEnum|null $navigationIcon = Heroicon::OutlinedUsers;

    protected static string|\UnitEnum|null $navigationGroup = 'customers';

    protected static ?int $navigationSort = 7;

    public function getTitle(): string
    {
        return __('filament/admin/reports.all_customers_statement');
    }

    public static function getNavigationLabel(): string
    {
        return __('filament/admin/reports.all_customers_statement');
    }

    public static function getNavigationGroup(): ?string
    {
        return __('filament.navigation_groups.customers');
    }

    public function mount(): void
    {
        $this->form->fill([
            'from_date' => now()->startOfMonth(),
            'to_date' => now()->endOfMonth(),
        ]);
        $this->generateReport();
    }

    public function form(Schema $schema): Schema
    {
        return $schema
            ->statePath('data')
            ->components([
                Section::make(__('filament/admin/reports.filters'))
                    ->columns(2)
                    ->schema([
                        DatePicker::make('from_date')
                            ->label(__('filament/admin/reports.from_date'))
                            ->native(false)
                            ->live()
                            ->afterStateUpdated(fn() => $this->generateReport()),

                        DatePicker::make('to_date')
                            ->label(__('filament/admin/reports.to_date'))
                            ->native(false)
                            ->live()
                            ->afterStateUpdated(fn() => $this->generateReport())
                            ->default(now())
                            ->required(),
                    ]),
            ]);
    }

    public function generateReport(): void
    {
        $formData = $this->form->getState();
        $from_date = isset($formData['from_date']) ? Carbon::parse($formData['from_date'])->startOfDay() : null;
        $to_date = isset($formData['to_date']) ? Carbon::parse($formData['to_date'])->endOfDay() : Carbon::now()->endOfDay();

        if ($from_date && $to_date->lt($from_date)) {
            \Filament\Notifications\Notification::make()
                ->title('تاريخ النهاية يجب أن يكون بعد أو يساوي تاريخ البداية')
                ->warning()
                ->send();
            $this->report_data = [];
            return;
        }

        $customers = Customer::all();
        $customers_data = [];

        foreach ($customers as $customer) {
            // حساب الرصيد الافتتاحي من قاعدة البيانات + المبيعات السابقة - المدفوعات السابقة
            $opening_balance_query = Sale::where('customer_id', $customer->id);
            if ($from_date) {
                $opening_balance_query->where('created_at', '<', $from_date);
            }
            $previous_sales = $opening_balance_query->sum('remaining_amount');

            // جلب المدفوعات السابقة للرصيد الافتتاحي
            $previous_payments_query = CustomerPayment::where('customer_id', $customer->id)
                ->where('status', 'confirmed');
            if ($from_date) {
                $previous_payments_query->where('created_at', '<', $from_date);
            }
            $previous_payments = $previous_payments_query->sum('amount');

            // جلب أذونات الصرف السابقة للعميل
            $previous_vouchers_query = \App\Models\SupplierPayment::where('customer_id', $customer->id)
                ->where('status', 'confirmed');
            if ($from_date) {
                $previous_vouchers_query->where('created_at', '<', $from_date);
            }
            $previous_vouchers = $previous_vouchers_query->sum('amount');

            // جلب المرتجعات السابقة للرصيد الافتتاحي
            $previous_returns_query = \App\Models\SaleReturn::where('customer_id', $customer->id);
            if ($from_date) {
                $previous_returns_query->where('created_at', '<', $from_date);
            }
            $previous_returns = $previous_returns_query->sum('remaining_amount');

            $opening_balance = ($customer->opening_balance ?? 0) + $previous_sales - $previous_payments + $previous_vouchers - $previous_returns;

            // جلب الفواتير في الفترة
            $sales_query = Sale::where('customer_id', $customer->id);
            if ($from_date) {
                $sales_query->where('created_at', '>=', $from_date);
            }
            $sales_query->where('created_at', '<=', $to_date);
            $sales = $sales_query->get();

            // جلب المدفوعات في الفترة
            $payments_query = CustomerPayment::where('customer_id', $customer->id)
                ->where('status', 'confirmed');
            if ($from_date) {
                $payments_query->where('created_at', '>=', $from_date);
            }
            $payments_query->where('created_at', '<=', $to_date);
            $payments = $payments_query->get();

            // جلب أذونات الصرف في الفترة
            $vouchers_query = \App\Models\SupplierPayment::where('customer_id', $customer->id)
                ->where('status', 'confirmed');
            if ($from_date) {
                $vouchers_query->where('created_at', '>=', $from_date);
            }
            $vouchers_query->where('created_at', '<=', $to_date);
            $vouchers = $vouchers_query->get();

            // جلب مرتجعات البيع في الفترة
            $returns_query = \App\Models\SaleReturn::where('customer_id', $customer->id);
            if ($from_date) {
                $returns_query->where('created_at', '>=', $from_date);
            }
            $returns_query->where('created_at', '<=', $to_date);
            $returns = $returns_query->get();

            $total_sales = $sales->sum('total_amount');
            $total_returns = $returns->sum('total_amount');
            $total_paid = $sales->sum('paid_amount');
            $total_payments = $payments->sum('amount');
            $total_vouchers = $vouchers->sum('amount');
            $closing_balance = $opening_balance + $sales->sum('remaining_amount') - $returns->sum('remaining_amount') - $total_payments + $total_vouchers;

            // حساب تاريخ آخر معاملة
            $last_transaction_date = null;
            $allDates = [];
            if ($sales->isNotEmpty()) {
                $allDates[] = $sales->max('created_at');
            }
            if ($payments->isNotEmpty()) {
                $allDates[] = $payments->max('created_at');
            }
            if ($returns->isNotEmpty()) {
                $allDates[] = $returns->max('created_at');
            }
            if (!empty($allDates)) {
                $last_transaction_date = max($allDates);
            }

            $customers_data[] = [
                'customer' => $customer,
                'opening_balance' => $opening_balance,
                'total_sales' => $total_sales,
                'total_returns' => $total_returns,
                'total_paid' => $total_paid,
                'total_payments' => $total_payments,
                'total_vouchers' => $total_vouchers,
                'closing_balance' => $closing_balance,
                'sales_count' => $sales->count(),
                'returns_count' => $returns->count(),
                'payments_count' => $payments->count(),
                'vouchers_count' => $vouchers->count(),
                'last_transaction_date' => $last_transaction_date,
            ];
        }

        // ترتيب حسب الرصيد الختامي (الأعلى أولاً)
        usort($customers_data, function($a, $b) {
            return $b['closing_balance'] <=> $a['closing_balance'];
        });

        $this->report_data = [
            'from_date' => $from_date?->format('Y-m-d'),
            'to_date' => $to_date->format('Y-m-d'),
            'customers' => $customers_data,
            'summary' => [
                'total_customers' => count($customers_data),
                'total_opening_balance' => array_sum(array_column($customers_data, 'opening_balance')),
                'total_sales' => array_sum(array_column($customers_data, 'total_sales')),
                'total_returns' => array_sum(array_column($customers_data, 'total_returns')),
                'total_paid' => array_sum(array_column($customers_data, 'total_paid')),
                'total_payments' => array_sum(array_column($customers_data, 'total_payments')),
                'total_vouchers' => array_sum(array_column($customers_data, 'total_vouchers')),
                'total_closing_balance' => array_sum(array_column($customers_data, 'closing_balance')),
            ],
        ];
    }

    public function getFilteredCustomersProperty()
    {
        if (empty($this->report_data) || empty($this->report_data['customers'])) {
            return [];
        }

        if (empty($this->search)) {
            return $this->report_data['customers'];
        }

        $search = mb_strtolower($this->search);
        return array_filter($this->report_data['customers'], function ($customer_data) use ($search) {
            $name = mb_strtolower($customer_data['customer']->name ?? '');
            $code = mb_strtolower($customer_data['customer']->code ?? '');
            $phone = mb_strtolower($customer_data['customer']->phone ?? '');

            return str_contains($name, $search) ||
                str_contains($code, $search) ||
                str_contains($phone, $search);
        });
    }

    public function exportExcel()
    {
        if (empty($this->report_data)) {
            $this->generateReport();
        }

        return Excel::download(
            new AllCustomersStatementExport($this->report_data['customers'], $this->data['from_date'], $this->data['to_date']),
            'all-customers-statement-' . now()->format('Y-m-d') . '.xlsx'
        );
    }

    public function exportPdf()
    {
        if (empty($this->report_data)) {
            $this->generateReport();
        }

        $mpdf = new Mpdf([
            'mode' => 'utf-8',
            'format' => 'A4',
            'orientation' => 'L',
            'default_font' => 'dejavusans',
            'autoScriptToLang' => true,
            'autoLangToFont' => true,
        ]);

        $mpdf->SetDirectionality('rtl');

        $html = view('reports.pdf.all-customers-statement', [
            'data' => $this->report_data['customers'],
            'from_date' => $this->data['from_date'],
            'to_date' => $this->data['to_date'],
        ])->render();

        $mpdf->WriteHTML($html);

        return response()->streamDownload(function () use ($mpdf) {
            echo $mpdf->Output('', 'S');
        }, 'all-customers-statement-' . now()->format('Y-m-d') . '.pdf');
    }

    public static function shouldRegisterNavigation(): bool
    {
        return true;
    }
}
