<?php

namespace App\Filament\Reports;

use App\Models\Product;
use App\Models\Sale;
use App\Models\Purchase;
use App\Models\Customer;
use App\Models\Supplier;
use EightyNine\Reports\Components\Text;
use EightyNine\Reports\Report;
use EightyNine\Reports\Components\Body;
use EightyNine\Reports\Components\Footer;
use EightyNine\Reports\Components\Header;
use Filament\Forms\Form;
use Filament\Forms\Components\DatePicker;
use Filament\Forms\Components\Select;
use Illuminate\Support\Carbon;

class SalesPurchaseReport extends Report
{
    protected static ?string $navigationIcon = 'heroicon-o-chart-bar';

    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);

        [$from, $to] = $dates;

        $from = Carbon::createFromFormat("d/m/Y", $from);
        $to = Carbon::createFromFormat("d/m/Y", $to);

        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("type")
                                    ->label("نوع المعاملة"),
                                Body\TextColumn::make("products")
                                    ->label("المنتجات"),
                                Body\TextColumn::make("party")
                                    ->label("الطرف (عميل/مورد)"),
                                Body\TextColumn::make("amount")
                                    ->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');
                                    }

                                    // Extract date range
                                    [$from, $to] = $this->getCarbonInstancesFromDateString($filters['date'] ?? null);
    
                                    // Make the date filter mandatory
                                    if (!$from || !$to) {
                                        return collect([]); // Return empty collection if no date filter
                                    }
    
                                    // Initialize queries for Sales and Purchases
                                    $salesQuery = Sale::with(['products', 'customer'])->orderBy('date', 'asc');
                                    $purchaseQuery = Purchase::with(['products', 'supplier'])->orderBy('date', 'asc');
    
                                    // Apply date filter
                                    $salesQuery->whereBetween('date', [$from, $to]);
                                    $purchaseQuery->whereBetween('date', [$from, $to]);
    
                                    // Apply optional filters for products, customers, and suppliers
                                    if (!empty($filters['product_id'])) {
                                        $salesQuery->whereHas('products', fn($q) => $q->where('id', $filters['product_id']));
                                        $purchaseQuery->whereHas('products', fn($q) => $q->where('id', $filters['product_id']));
                                    }
    
                                    if (!empty($filters['customer_id'])) {
                                        $salesQuery->where('customer_id', $filters['customer_id']);
                                    }
    
                                    if (!empty($filters['supplier_id'])) {
                                        $purchaseQuery->where('supplier_id', $filters['supplier_id']);
                                    }
    
                                    // Fetch data
                                    $sales = $salesQuery->get();
                                    $purchases = $purchaseQuery->get();
    
                                    // Merge transactions and calculate balance
                                    $transactions = $sales->map(fn($sale) => [
                                        'date' => $sale->date,
                                        'type' => 'بيع',
                                        'products' => $sale->products ? $sale->products->pluck('name')->implode(', ') : 'N/A',
                                        'party' => $sale->customer->name,
                                        'amount' => $sale->products->sum('pivot.total'), // Calculate sum from pivot table
                                    ])->merge(
                                        $purchases->map(fn($purchase) => [
                                            'date' => $purchase->date,
                                            'type' => 'شراء',
                                            'products' => $purchase->products ? $purchase->products->pluck('name')->implode(', ') : 'N/A',
                                            'party' => $purchase->supplier->name,
                                            'amount' => -$purchase->products->sum('pivot.total'), // Calculate sum from pivot table
                                        ])
                                    )->sortBy('date');
    
                                    $balance = 0;
    
                                    return $transactions->map(function ($transaction) use (&$balance) {
                                        $balance += $transaction['amount'];
                                        return array_merge($transaction, ['balance' => $balance]);
                                    });
                                }
                            ),
                    ]),
            ]);
    }
    
    public function footer(Footer $footer): Footer
    {
        return $footer
            ->schema([
                Text::make("تاريخ التقرير: " . now()->format("d/m/Y H:i:s"))
                    ->subtitle(),
            ]);
    }

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

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

                Select::make('product_id')
                    ->label('المنتجات')
                    ->options(
                        Product::all()->pluck('name', 'id')->toArray()
                    )
                    ->placeholder('اختر المنتج')
                    ->preload()
                    ->multiple(),

                Select::make('customer_id')
                    ->label('العملاء')
                    ->options(
                        Customer::all()->pluck('name', 'id')->toArray()
                    )
                    ->placeholder('حدد العميل')
                    ->preload()
                    ->multiple(),

                Select::make('supplier_id')
                    ->label('الموردين')
                    ->options(
                        Supplier::all()->pluck('name', 'id')->toArray()
                    )
                    ->placeholder('حدد المورد')
                    ->preload()
                    ->multiple(),
            ]);
    }
}
