<?php

namespace App\Filament\Reports;

use App\Models\Product;
use App\Models\Sale;
use App\Models\Purchase;
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\Select;
use Filament\Forms\Components\DatePicker;
use Illuminate\Support\Carbon;

class AllProductsReport extends Report
{
    protected static ?string $navigationIcon = 'heroicon-o-cube';

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

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

    protected static ?int $navigationSort = 11;

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

        if (count($dates) !== 2) {
            return [null, null];
        }

        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("product_name")->label("اسم المنتج"),
                                Body\TextColumn::make("initial_stock")->label("المخزون الأولي"),
                                Body\TextColumn::make("total_sales")->label("إجمالي الصرف"),
                                Body\TextColumn::make("total_purchases")->label("إجمالي الوارد"),
                                Body\TextColumn::make("final_stock")->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 valid date range
                                    }

                                    $products = Product::query();

                                    // Filter by product if selected
                                    if (!empty($filters['product_id'])) {
                                        $products->where('id', $filters['product_id']);
                                    }

                                    $products = $products->get();

                                    $totals = [
                                        'initial_stock' => 0,
                                        'total_sales' => 0,
                                        'total_purchases' => 0,
                                        'final_stock' => 0,
                                    ];

                                    $data = $products->map(function ($product) use ($from, $to, &$totals) {
                                        // Initial stock
                                        $initialStock = $product->stock;

                                        // Subtract sales before the date range
                                        $salesBefore = Sale::whereHas('products', function ($query) use ($product) {
                                            $query->where('products.id', $product->id);
                                        })->where('sales.date', '<', $from)->get();

                                        $initialStock -= $salesBefore->reduce(function ($carry, $sale) use ($product) {
                                            return $carry + $sale->products->find($product->id)->pivot->quantity;
                                        }, 0);

                                        // Add purchases before the date range
                                        $purchasesBefore = Purchase::whereHas('products', function ($query) use ($product) {
                                            $query->where('products.id', $product->id);
                                        })->where('purchases.date', '<', $from)->get();

                                        $initialStock += $purchasesBefore->reduce(function ($carry, $purchase) use ($product) {
                                            return $carry + $purchase->products->find($product->id)->pivot->quantity;
                                        }, 0);

                                        // In-date range sales and purchases
                                        $salesInRange = Sale::whereHas('products', function ($query) use ($product) {
                                            $query->where('products.id', $product->id);
                                        })->whereBetween('sales.date', [$from, $to])->get();

                                        $purchasesInRange = Purchase::whereHas('products', function ($query) use ($product) {
                                            $query->where('products.id', $product->id);
                                        })->whereBetween('purchases.date', [$from, $to])->get();

                                        $totalSales = $salesInRange->reduce(function ($carry, $sale) use ($product) {
                                            return $carry + $sale->products->find($product->id)->pivot->quantity;
                                        }, 0);

                                        $totalPurchases = $purchasesInRange->reduce(function ($carry, $purchase) use ($product) {
                                            return $carry + $purchase->products->find($product->id)->pivot->quantity;
                                        }, 0);

                                        // Final stock
                                        $finalStock = $initialStock + $totalPurchases - $totalSales;

                                        // Accumulate totals
                                        $totals['initial_stock'] += $initialStock;
                                        $totals['total_sales'] += $totalSales;
                                        $totals['total_purchases'] += $totalPurchases;
                                        $totals['final_stock'] += $finalStock;

                                        return [
                                            'product_name' => $product->name,
                                            'initial_stock' => $initialStock,
                                            'total_sales' => $totalSales,
                                            'total_purchases' => $totalPurchases,
                                            'final_stock' => $finalStock,
                                        ];
                                    });

                                    // Add totals row
                                    $data->push([
                                        'product_name' => 'الإجمالي',
                                        'initial_stock' => $totals['initial_stock'],
                                        'total_sales' => $totals['total_sales'],
                                        'total_purchases' => $totals['total_purchases'],
                                        'final_stock' => $totals['final_stock'],
                                    ]);

                                    return $data;
                                }
                            ),
                    ]),
            ]);
    }

    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'))
                    ->placeholder('اختر منتجًا'),
            ]);
    }
}
