<?php

namespace App\Livewire\Reports;

use App\Models\Sale;
use App\Models\SaleItem;
use App\Models\PurchaseOrder;
use App\Models\PurchaseOrderItem;
use App\Models\Setting;
use App\Exports\GenericExport;
use Maatwebsite\Excel\Facades\Excel;
use Illuminate\Support\Facades\DB;
use Livewire\Component;

class ProfitLossReport extends Component
{
    public string $dateFrom = '';
    public string $dateTo = '';
    public string $branchFilter = '';

    public function mount()
    {
        $this->dateFrom = now()->startOfMonth()->format('Y-m-d');
        $this->dateTo = now()->format('Y-m-d');
    }

    public function getRevenueProperty()
    {
        return Sale::query()
            ->when($this->dateFrom, fn($q) => $q->whereDate('created_at', '>=', $this->dateFrom))
            ->when($this->dateTo, fn($q) => $q->whereDate('created_at', '<=', $this->dateTo))
            ->when($this->branchFilter, fn($q) => $q->where('branch_id', $this->branchFilter))
            ->sum('total');
    }

    public function getCostOfGoodsSoldProperty()
    {
        // Get the cost from sale items
        return SaleItem::query()
            ->whereHas('sale', function ($q) {
                $q->when($this->dateFrom, fn($sq) => $sq->whereDate('created_at', '>=', $this->dateFrom))
                  ->when($this->dateTo, fn($sq) => $sq->whereDate('created_at', '<=', $this->dateTo))
                  ->when($this->branchFilter, fn($sq) => $sq->where('branch_id', $this->branchFilter));
            })
            ->join('products', 'sale_items.product_id', '=', 'products.id')
            ->selectRaw('SUM(sale_items.quantity * products.cost_price) as total')
            ->value('total') ?? 0;
    }

    public function getDiscountsProperty()
    {
        return Sale::query()
            ->when($this->dateFrom, fn($q) => $q->whereDate('created_at', '>=', $this->dateFrom))
            ->when($this->dateTo, fn($q) => $q->whereDate('created_at', '<=', $this->dateTo))
            ->when($this->branchFilter, fn($q) => $q->where('branch_id', $this->branchFilter))
            ->sum('discount');
    }

    public function getSalesByCategory()
    {
        return SaleItem::query()
            ->whereHas('sale', function ($q) {
                $q->when($this->dateFrom, fn($sq) => $sq->whereDate('created_at', '>=', $this->dateFrom))
                  ->when($this->dateTo, fn($sq) => $sq->whereDate('created_at', '<=', $this->dateTo));
            })
            ->join('products', 'sale_items.product_id', '=', 'products.id')
            ->join('categories', 'products.category_id', '=', 'categories.id')
            ->select('categories.name', 'categories.color', DB::raw('SUM(sale_items.total) as revenue'))
            ->groupBy('categories.id', 'categories.name', 'categories.color')
            ->orderByDesc('revenue')
            ->get();
    }

    public function getSalesByPaymentMethod()
    {
        return Sale::query()
            ->when($this->dateFrom, fn($q) => $q->whereDate('sales.created_at', '>=', $this->dateFrom))
            ->when($this->dateTo, fn($q) => $q->whereDate('sales.created_at', '<=', $this->dateTo))
            ->join('payment_methods', 'sales.payment_method_id', '=', 'payment_methods.id')
            ->select('payment_methods.name', DB::raw('SUM(sales.total) as amount'), DB::raw('COUNT(*) as count'))
            ->groupBy('payment_methods.id', 'payment_methods.name')
            ->get();
    }

    public function export()
    {
        $revenue = $this->revenue;
        $cogs = $this->costOfGoodsSold;
        $discounts = $this->discounts;
        $grossProfit = $revenue - $cogs;
        $grossMargin = $revenue > 0 ? ($grossProfit / $revenue) * 100 : 0;

        $summaryData = collect([
            (object)[
                'metric' => __('Revenue'),
                'value' => number_format($revenue, 2),
            ],
            (object)[
                'metric' => __('COGS'),
                'value' => number_format($cogs, 2),
            ],
            (object)[
                'metric' => __('Discounts'),
                'value' => number_format($discounts, 2),
            ],
            (object)[
                'metric' => __('Gross Profit'),
                'value' => number_format($grossProfit, 2),
            ],
            (object)[
                'metric' => __('Gross Margin'),
                'value' => number_format($grossMargin, 2) . '%',
            ],
        ]);

        return Excel::download(new GenericExport(
            $summaryData,
            ['Metric', 'Value'],
            function ($row) {
                return [
                    $row->metric,
                    $row->value,
                ];
            },
            'Profit_Loss_Summary_' . now()->format('Y-m-d')
        ), 'profit_loss_' . now()->format('YmdHis') . '.xlsx');
    }

    public function render()
    {
        $revenue = $this->revenue;
        $cogs = $this->costOfGoodsSold;
        $discounts = $this->discounts;
        $grossProfit = $revenue - $cogs;
        $grossMargin = $revenue > 0 ? ($grossProfit / $revenue) * 100 : 0;

        $branches = \App\Models\Branch::active()->get();

        return view('livewire.reports.profit-loss', [
            'revenue' => $revenue,
            'cogs' => $cogs,
            'discounts' => $discounts,
            'grossProfit' => $grossProfit,
            'grossMargin' => $grossMargin,
            'salesByCategory' => $this->getSalesByCategory(),
            'salesByPaymentMethod' => $this->getSalesByPaymentMethod(),
            'branches' => $branches,
            'currency' => Setting::get('default_currency', 'EGP'),
        ]);
    }
}
