<?php

namespace App\Filament\Pages;

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

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

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

    public ?array $data = [];
    public array $statement_data = [];

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

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

    protected static ?int $navigationSort = 8;

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

    public static function getNavigationLabel(): string
    {
        return __('filament/admin/reports.farm_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(),
        ]);
    }

    public function form(Schema $schema): Schema
    {
        return $schema
            ->statePath('data')
            ->components([
                Section::make(__('filament/admin/reports.filters'))
                    ->columns(3)
                    ->schema([
                        Select::make('farm_id')
                            ->label(__('filament/admin/farm_resource.farm'))
                            ->placeholder(__('filament/admin/farm_resource.select_farm'))
                            ->options(\App\Models\Farm::pluck('name', 'id'))
                            ->searchable()
                            ->preload()
                            ->required()
                            ->live()
                            ->afterStateUpdated(function ($state, \Filament\Schemas\Components\Utilities\Set $set) {
                                $set('breeding_cycle_id', null);
                            }),

                        Select::make('breeding_cycle_id')
                            ->label(__('filament/admin/reports.breeding_cycle'))
                            ->placeholder(__('filament/admin/reports.select_breeding_cycle'))
                            ->options(fn($get) => filled($get('farm_id'))
                                ? BreedingCycle::query()
                                    ->where('farm_id', $get('farm_id'))
                                    ->orderBy('name')
                                    ->pluck('name', 'id')
                                : [])
                            ->searchable()
                            ->preload()
                            ->disabled(fn($get) => blank($get('farm_id')))
                            ->native(false)
                            ->nullable(),

                        DatePicker::make('from_date')
                            ->label(__('filament/admin/reports.from_date'))
                            ->native(false),

                        DatePicker::make('to_date')
                            ->label(__('filament/admin/reports.to_date'))
                            ->native(false),
                    ]),
            ]);
    }

    public function generateStatement(): void
    {
        $formData = $this->form->getState();
        $farm_id = $formData['farm_id'] ?? null;
        $breeding_cycle_id = $formData['breeding_cycle_id'] ?? null;
        
        if (!$farm_id) {
            $this->statement_data = [];
            return;
        }

        $farm = Farm::with('customer')->findOrFail($farm_id);
        $from_date = isset($formData['from_date']) ? Carbon::parse($formData['from_date']) : null;
        $to_date = isset($formData['to_date']) ? Carbon::parse($formData['to_date'])->endOfDay() : Carbon::now();

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

        // حساب الرصيد الافتتاحي
        $opening_balance_query = Sale::where('farm_id', $farm_id);
        if ($breeding_cycle_id) {
            $opening_balance_query->where('breeding_cycle_id', $breeding_cycle_id);
        }
        
        if ($from_date) {
            $opening_balance_query->where('created_at', '<', $from_date);
        }

        $opening_balance = $opening_balance_query->sum('remaining_amount');
        
        // جلب فواتير البيع
        $sales_query = Sale::where('farm_id', $farm_id);
        if ($breeding_cycle_id) {
            $sales_query->where('breeding_cycle_id', $breeding_cycle_id);
        }
        
        if ($from_date) {
            $sales_query->where('created_at', '>=', $from_date);
        }
        
        $sales_query->where('created_at', '<=', $to_date);

        $sales = $sales_query->with(['items.product', 'items.unit'])->orderBy('created_at')->get();

        // جلب مرتجعات البيع
        $returns_query = SaleReturn::where('farm_id', $farm_id);
        if ($breeding_cycle_id) {
            $returns_query->where('breeding_cycle_id', $breeding_cycle_id);
        }
        
        if ($from_date) {
            $returns_query->where('created_at', '>=', $from_date);
        }
        
        $returns_query->where('created_at', '<=', $to_date);

        $returns = $returns_query->with(['items.product', 'items.unit'])->orderBy('created_at')->get();

        // دمج جميع المعاملات وترتيبها حسب التاريخ
        $transactions = collect();
        
        foreach ($sales as $sale) {
            $itemsDisplay = [];
            foreach ($sale->items as $item) {
                $qtyDisplay = $item->quantity == floor($item->quantity)
                    ? (int) $item->quantity
                    : number_format($item->quantity, 3);

                $discountDisplay = '';
                if (($item->discount_percentage ?? 0) > 0) {
                    $discountDisplay = $item->discount_percentage . '%';
                } elseif (($item->discount_amount ?? 0) > 0) {
                    $discountDisplay = number_format($item->discount_amount, 2);
                }

                $itemsDisplay[] = [
                    'product_name' => $item->product?->name ?? 'منتج غير معروف',
                    'quantity' => $qtyDisplay,
                    'unit_name' => $item->unit?->name ?? '',
                    'unit_price' => number_format($item->unit_price ?? 0, 2),
                    'discount' => $discountDisplay,
                ];
            }

            $transactions->push([
                'date' => $sale->created_at,
                'type' => 'sale',
                'reference' => $sale->sale_number,
                'description' => __('filament/admin/reports.sale_invoice'),
                'subtotal' => $sale->subtotal,
                'discount' => $sale->discount_amount,
                'tax' => $sale->tax_amount,
                'total' => $sale->total_amount,
                'paid' => $sale->paid_amount,
                'remaining' => $sale->remaining_amount,
                'items' => $sale->items,
                'items_display' => $itemsDisplay,
            ]);
        }

        foreach ($returns as $return) {
            $itemsDisplay = [];
            foreach ($return->items as $item) {
                $qtyDisplay = $item->quantity == floor($item->quantity)
                    ? (int) $item->quantity
                    : number_format($item->quantity, 3);

                $discountDisplay = '';
                if (($item->discount_percentage ?? 0) > 0) {
                    $discountDisplay = $item->discount_percentage . '%';
                } elseif (($item->discount_amount ?? 0) > 0) {
                    $discountDisplay = number_format($item->discount_amount, 2);
                }

                $itemsDisplay[] = [
                    'product_name' => $item->product?->name ?? 'منتج غير معروف',
                    'quantity' => $qtyDisplay,
                    'unit_name' => $item->unit?->name ?? '',
                    'unit_price' => number_format($item->unit_price ?? 0, 2),
                    'discount' => $discountDisplay,
                ];
            }

            $transactions->push([
                'date' => $return->created_at,
                'type' => 'return',
                'reference' => $return->return_number,
                'description' => __('filament/admin/reports.sale_return'),
                'subtotal' => -$return->subtotal,
                'discount' => -$return->discount_amount,
                'tax' => -$return->tax_amount,
                'total' => -$return->total_amount,
                'paid' => -$return->paid_amount,
                'remaining' => -$return->remaining_amount,
                'items' => $return->items,
                'items_display' => $itemsDisplay,
            ]);
        }

        $transactions = $transactions->sortBy('date')->values();

        // حساب الرصيد الجاري
        $running_balance = $opening_balance;
        $transactions = $transactions->map(function ($transaction) use (&$running_balance) {
            $running_balance += $transaction['remaining'];
            $transaction['running_balance'] = $running_balance;
            return $transaction;
        });

        // حساب الإجماليات
        $total_sales = $sales->sum('total_amount');
        $total_paid = $sales->sum('paid_amount');
        $total_remaining = $sales->sum('remaining_amount');
        $total_returns = $returns->sum('total_amount');
        $closing_balance = $opening_balance + $sales->sum('remaining_amount') - $returns->sum('remaining_amount');

        $this->statement_data = [
            'farm' => $farm,
            'customer' => $farm->customer,
            'from_date' => $from_date?->format('Y-m-d'),
            'to_date' => $to_date->format('Y-m-d'),
            'opening_balance' => $opening_balance,
            'closing_balance' => $closing_balance,
            'transactions' => $transactions,
            'totals' => [
                'sales' => $total_sales,
                'returns' => $total_returns,
                'paid' => $total_paid,
                'remaining' => $total_remaining,
                'invoices_count' => $sales->count(),
                'returns_count' => $returns->count(),
            ],
        ];
    }

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

        $farm = Farm::find($this->data['farm_id']);

        return Excel::download(
            new FarmStatementExport($this->statement_data, $this->data['from_date'], $this->data['to_date']),
            'farm-statement-' . $farm->name . '-' . now()->format('Y-m-d') . '.xlsx'
        );
    }

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

        $farm = Farm::find($this->data['farm_id']);

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

        $mpdf->SetDirectionality('rtl');

        $html = view('reports.pdf.farm-statement', [
            'data' => $this->statement_data,
        ])->render();

        $mpdf->WriteHTML($html);

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