<?php

namespace App\Livewire\Dashboard;

use App\Domain\Financial\Models\Payment;
use App\Domain\Shared\Traits\UsesBranchScope;
use Illuminate\Support\Facades\DB;
use Livewire\Component;

class ProductRevenueWidget extends Component
{
    use UsesBranchScope;

    public string $period = 'month';

    public function render()
    {
        $startDate = match ($this->period) {
            'today' => now()->startOfDay(),
            'week' => now()->startOfWeek(),
            'month' => now()->startOfMonth(),
            'year' => now()->startOfYear(),
            default => now()->startOfMonth(),
        };

        $previousStart = match ($this->period) {
            'today' => now()->subDay()->startOfDay(),
            'week' => now()->subWeek()->startOfWeek(),
            'month' => now()->subMonth()->startOfMonth(),
            'year' => now()->subYear()->startOfYear(),
            default => now()->subMonth()->startOfMonth(),
        };

        $academyId = app('current_academy')?->id;
        $branchId = $this->getActiveBranchId();
        $productType = 'App\\Domain\\Inventory\\Models\\Product';

        // Current period product revenue (pro-rata)
        $totalProductRevenue = $this->getProductRevenue($startDate, null, $academyId, $branchId, $productType);

        // Previous period
        $previousProductRevenue = $this->getProductRevenue($previousStart, $startDate, $academyId, $branchId, $productType);

        $change = $previousProductRevenue > 0
            ? round(($totalProductRevenue - $previousProductRevenue) / $previousProductRevenue * 100, 1)
            : ($totalProductRevenue > 0 ? 100 : 0);

        // Revenue per product
        $byProduct = $this->getRevenueByProduct($startDate, $academyId, $branchId, $productType);

        // Total confirmed payments this period
        $totalRevenue = Payment::where('direction', 'inbound')->where('status', 'confirmed')
            ->where('created_at', '>=', $startDate)
            ->when($academyId, fn ($q) => $q->where('academy_id', $academyId))
            ->when($branchId, fn ($q) => $q->where('branch_id', $branchId))
            ->sum('amount');

        $productPercent = $totalRevenue > 0
            ? round($totalProductRevenue / $totalRevenue * 100, 1)
            : 0;

        // Total units sold this period
        $unitsSold = DB::table('invoice_items')
            ->join('invoices', 'invoice_items.invoice_id', '=', 'invoices.id')
            ->join('payments', 'payments.invoice_id', '=', 'invoices.id')
            ->where('invoice_items.itemable_type', $productType)
            ->where('payments.status', 'confirmed')
            ->where('payments.direction', 'inbound')
            ->whereNull('payments.deleted_at')
            ->whereNull('invoices.deleted_at')
            ->where('invoices.status', '!=', 'cancelled')
            ->where('payments.created_at', '>=', $startDate)
            ->when($academyId, fn ($q) => $q->where('payments.academy_id', $academyId))
            ->when($branchId, fn ($q) => $q->where('payments.branch_id', $branchId))
            ->sum('invoice_items.quantity');

        return view('livewire.dashboard.product-revenue-widget', [
            'totalProductRevenue' => $totalProductRevenue,
            'change' => $change,
            'byProduct' => $byProduct,
            'productPercent' => $productPercent,
            'totalRevenue' => $totalRevenue,
            'unitsSold' => $unitsSold,
        ]);
    }

    private function getProductRevenue($from, $to, $academyId, ?int $branchId, string $productType): int
    {
        $result = DB::table('payments')
            ->join('invoices', 'payments.invoice_id', '=', 'invoices.id')
            ->joinSub(
                DB::table('invoice_items')
                    ->where('itemable_type', $productType)
                    ->select('invoice_id', DB::raw('SUM(total_amount) as product_total'))
                    ->groupBy('invoice_id'),
                'prod_items',
                'prod_items.invoice_id', '=', 'invoices.id'
            )
            ->where('payments.status', 'confirmed')
            ->where('payments.direction', 'inbound')
            ->whereNull('payments.deleted_at')
            ->whereNull('invoices.deleted_at')
            ->where('invoices.status', '!=', 'cancelled')
            ->where('invoices.subtotal_amount', '>', 0)
            ->where('payments.created_at', '>=', $from)
            ->when($to, fn ($q) => $q->where('payments.created_at', '<', $to))
            ->when($academyId, fn ($q) => $q->where('payments.academy_id', $academyId))
            ->when($branchId, fn ($q) => $q->where('payments.branch_id', $branchId))
            ->select(
                DB::raw('SUM(payments.amount * prod_items.product_total / invoices.subtotal_amount) as product_revenue')
            )
            ->value('product_revenue');

        return (int) ($result ?? 0);
    }

    private function getRevenueByProduct($from, $academyId, ?int $branchId, string $productType)
    {
        return DB::table('payments')
            ->join('invoices', 'payments.invoice_id', '=', 'invoices.id')
            ->join('invoice_items', function ($j) use ($productType) {
                $j->on('invoice_items.invoice_id', '=', 'invoices.id')
                  ->where('invoice_items.itemable_type', '=', $productType);
            })
            ->join('products', 'invoice_items.itemable_id', '=', 'products.id')
            ->where('payments.status', 'confirmed')
            ->where('payments.direction', 'inbound')
            ->whereNull('payments.deleted_at')
            ->whereNull('invoices.deleted_at')
            ->where('invoices.status', '!=', 'cancelled')
            ->where('invoices.subtotal_amount', '>', 0)
            ->where('payments.created_at', '>=', $from)
            ->when($academyId, fn ($q) => $q->where('payments.academy_id', $academyId))
            ->when($branchId, fn ($q) => $q->where('payments.branch_id', $branchId))
            ->select(
                'products.id as product_id',
                'products.name_ar as product_name',
                DB::raw('SUM(payments.amount * invoice_items.total_amount / invoices.subtotal_amount) as total'),
                DB::raw('SUM(invoice_items.quantity) as units_sold'),
                DB::raw('COUNT(DISTINCT invoices.id) as invoice_count'),
            )
            ->groupBy('products.id', 'products.name_ar')
            ->orderByDesc('total')
            ->limit(15)
            ->get();
    }
}
