<?php

namespace App\Filament\Reports;

use App\Models\MonyImport;
use App\Models\MonyExport;
use App\Models\Customer;
use App\Models\Supplier;
use App\Models\Employee;
use App\Models\Equip;
use App\Models\Land;
use App\Models\MonyType;
use EightyNine\Reports\Components\Text;
use EightyNine\Reports\Report;
use EightyNine\Reports\Components\Body;
use EightyNine\Reports\Components\Header;
use Filament\Forms\Form;
use Filament\Forms\Components\DatePicker;
use Filament\Forms\Components\Select;
use Illuminate\Support\Carbon;

class MonyReport extends Report
{
    protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack';

    public static function getNavigationLabel(): string
    {
        return "تقرير الخزينه";
    }

    public function getTitle(): string
    {
        return "تقرير الخزينه";
    }

    protected static ?int $navigationSort = 5;

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

    public function header(Header $header): Header
    {
        return $header
            ->schema([
                Header\Layout\HeaderRow::make()
                    ->schema([
                        Text::make("حركة النقديه بالخزينه")
                            ->fontXl()
                            ->fontBold()
                            ->primary(),
                        Text::make("يحتوي هذا القسم على معاملات صرف و وارد نقديه بين النطاق الزمني المحدد.")
                            ->fontSm()
                            ->secondary(),
                    ])
                    ->alignBottom(),
            ]);
    }

    function getCarbonInstancesFromDateString(?string $dateString): array
    {
        if (!$dateString) {
            return [null, null];
        }

        $dates = explode(" - ", $dateString);

        try {
            $from = Carbon::createFromFormat("d/m/Y", $dates[0]);
            $to = Carbon::createFromFormat("d/m/Y", $dates[1]);
        } catch (\Exception $e) {
            return [null, null];
        }

        return [$from, $to];
    }

    public function body(Body $body): Body
    {
        return $body
            ->schema([
                Body\Layout\BodyColumn::make()
                    ->schema([
                        Body\Table::make()
                            ->columns([
                                Body\TextColumn::make("date")->date('D-d-M-Y')->label("التاريخ"),
                                Body\TextColumn::make("land_name")->label("الأرض"),
                                Body\TextColumn::make("employee_name")->label("العامل"),
                                Body\TextColumn::make("value_in")->label("وارد نقدي"),
                                Body\TextColumn::make("value_out")->label("صرف نقدي"),
                                Body\TextColumn::make("notes")->html()->label("الملاحظات"),
                                Body\TextColumn::make("balance")->label("الرصيد"),
                            ])
                            ->data(
                                function (?array $filters) {
                                    if (empty($filters['date']) && !empty($filters['from_date']) && !empty($filters['to_date'])) {
                                        $filters['date'] = Carbon::parse($filters['from_date'])->format('d/m/Y') . ' - ' . Carbon::parse($filters['to_date'])->format('d/m/Y');
                                    }

                                    [$from, $to] = $this->getCarbonInstancesFromDateString($filters['date'] ?? null);
    
                                    if (!$from || !$to) {
                                        return collect([]); // Ensure a valid date range
                                    }
    
                                    $importsQuery = MonyImport::with(['monyType', 'lands'])
                                        ->whereBetween('date', [$from, $to]);
    
                                    $exportsQuery = MonyExport::with(['monyType', 'lands', 'employee'])
                                        ->whereBetween('date', [$from, $to]);
    
                                    // ✅ Apply land filtering using `whereHas()` instead of `whereIn()`
                                    if (!empty($filters['land_id']) && !in_array('all', $filters['land_id'])) {
                                        $importsQuery->whereHas('lands', function ($query) use ($filters) {
                                            $query->whereIn('lands.id', $filters['land_id']);
                                        });
    
                                        $exportsQuery->whereHas('lands', function ($query) use ($filters) {
                                            $query->whereIn('lands.id', $filters['land_id']);
                                        });
                                    }
    
                                    // ✅ Apply other filters only if they are set
                                    foreach (['customer_id', 'equip_id', 'supplier_id', 'employee_id', 'mony_type_id'] as $filterKey) {
                                        if (!empty($filters[$filterKey]) && !in_array('all', $filters[$filterKey])) {
                                            $importsQuery->whereIn($filterKey, $filters[$filterKey]);
                                            $exportsQuery->whereIn($filterKey, $filters[$filterKey]);
                                        }
                                    }
    
                                    $imports = $importsQuery->orderBy('date', 'asc')->get();
                                    $exports = $exportsQuery->orderBy('date', 'asc')->get();
    
                                    // Calculate initial balance
                                    $initialBalance = MonyImport::where('date', '<', $from)->sum('value')
                                        - MonyExport::where('date', '<', $from)->sum('value');
    
                                    $runningBalance = $initialBalance;
    
                                    // Combine imports and exports
                                    $transactions = $imports->map(function ($transaction) {
                                        return [
                                            'date' => $transaction->date,
                                            'land_name' => $transaction->lands->pluck('name')->join(', ') ?? '',
                                            'employee_name' => '---',
                                            'value_in' => $transaction->value,
                                            'value_out' => 0,
                                            'notes' => $transaction->monyType->name . "  " . $transaction->notes,
                                        ];
                                    })->toArray();
    
                                    $exportsArray = $exports->map(function ($transaction) {
                                        return [
                                            'date' => $transaction->date,
                                            'land_name' => $transaction->lands->pluck('name')->join(', ') ?? '',
                                            'employee_name' => $transaction->employee->name ?? '',
                                            'value_in' => 0,
                                            'value_out' => $transaction->value,
                                            'notes' => $transaction->monyType->name . "  " . $transaction->notes,
                                        ];
                                    })->toArray();
    
                                    // Merge and sort transactions
                                    $mergedTransactions = array_merge($transactions, $exportsArray);
                                    usort($mergedTransactions, fn ($a, $b) => strtotime($a['date']) <=> strtotime($b['date']));
    
                                    // Process transactions
                                    $totals = ['value_in' => 0, 'value_out' => 0];
    
                                    $data = collect($mergedTransactions)->map(function ($transaction) use (&$runningBalance, &$totals) {
                                        $totals['value_in'] += $transaction['value_in'];
                                        $totals['value_out'] += $transaction['value_out'];
    
                                        $runningBalance += $transaction['value_in'];
                                        $runningBalance -= $transaction['value_out'];
    
                                        return [
                                            'date' => $transaction['date'],
                                            'land_name' => $transaction['land_name'],
                                            'employee_name' => $transaction['employee_name'],
                                            'value_in' => $transaction['value_in'],
                                            'value_out' => $transaction['value_out'],
                                            'notes' => $transaction['notes'],
                                            'balance' => $runningBalance,
                                        ];
                                    });
    
                                    // Add totals row
                                    $data->push([
                                        'date' => null,
                                        'land_name' => '',
                                        'employee_name' => '',
                                        'value_in' => $totals['value_in'],
                                        'value_out' => $totals['value_out'],
                                        'notes' => 'الإجمالي',
                                        'balance' => '---',
                                    ]);
    
                                    return $data;
                                }
                            ),
                    ]),
            ]);
    }
    
    public function filterForm(Form $form): Form
    {
        $allOption = ['all' => 'الكل'];

        return $form
            ->schema([
                DatePicker::make('from_date')->label('من تاريخ')->native(false)->required(),

                DatePicker::make('to_date')->label('إلى تاريخ')->native(false)->required(),

                Select::make('mony_type_id')->label('البنود الماليه')->options($allOption + MonyType::pluck('name', 'id')->toArray())->multiple(),

                Select::make('customer_id')->label('العميل')->options($allOption + Customer::pluck('name', 'id')->toArray())->multiple(),

                Select::make('equip_id')->label('المعده')->options($allOption + Equip::pluck('type', 'id')->toArray())->multiple(),

                Select::make('supplier_id')->label('المورد')->options($allOption + Supplier::pluck('name', 'id')->toArray())->multiple(),

                Select::make('land_id')->label('الأرض')->options($allOption + Land::pluck('name', 'id')->toArray())->multiple(),

                Select::make('employee_id')->label('العمال')->options($allOption + Employee::pluck('name', 'id')->toArray())->multiple(),
            ]);
    }
}
