<?php

namespace App\Livewire\Inventory;

use App\Domain\Financial\Models\InvoiceItem;
use App\Domain\Inventory\Enums\MovementDirection;
use App\Domain\Inventory\Models\InventoryMovement;
use App\Domain\Inventory\Models\Product;
use App\Domain\POS\Models\POSTransaction;
use App\Domain\POS\Models\POSTransactionItem;
use Livewire\Attributes\Layout;
use Livewire\Attributes\Title;
use Livewire\Component;

#[Layout('layouts.app')]
#[Title('تفاصيل المنتج')]
class ProductShow extends Component
{
    public Product $product;

    public function mount(Product $product): void
    {
        $this->authorize('inventory.list');
        $this->product = $product->load(['category', 'inventoryLevels.warehouse', 'branch']);
    }

    public function render()
    {
        $levels = $this->product->inventoryLevels;

        $totalOnHand = $levels->sum('quantity_on_hand');
        $totalReserved = $levels->sum('quantity_reserved');
        $totalAvailable = $levels->sum('quantity_available');

        $movements = InventoryMovement::where('product_id', $this->product->id)
            ->with('warehouse')
            ->orderByDesc('created_at')
            ->limit(30)
            ->get();

        // Analytics — revenue from InvoiceItem (works regardless of track_inventory)
        $soldQuery = InvoiceItem::where('itemable_type', Product::class)
            ->where('itemable_id', $this->product->id)
            ->join('invoices', 'invoice_items.invoice_id', '=', 'invoices.id')
            ->whereNotIn('invoices.status', ['cancelled', 'refunded']);

        $totalRevenue   = (clone $soldQuery)->sum('invoice_items.total_amount');
        $totalUnitsSold = (clone $soldQuery)->sum('invoice_items.quantity');

        $firstSale = (clone $soldQuery)
            ->orderBy('invoice_items.created_at')
            ->value('invoice_items.created_at');

        // Collected (installment-aware): pro-rata share of invoice.paid_amount
        // = SUM( item_total / invoice_total * paid_amount ) per invoice
        // Works correctly for mixed invoices (product + program) because the
        // price override always lands on the program line, not the product line.
        $totalCollected = (int) (clone $soldQuery)
            ->selectRaw('SUM(
                CASE
                    WHEN invoices.total_amount > 0
                    THEN (invoice_items.total_amount::float / invoices.total_amount) * invoices.paid_amount
                    ELSE 0
                END
            ) as collected')
            ->value('collected');

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

        // Stock-in from movements (genuinely a stock concept)
        $totalIn = InventoryMovement::where('product_id', $this->product->id)
            ->where('direction', MovementDirection::In->value)
            ->sum('quantity');

        $monthsActive = 1;
        if ($firstSale) {
            // From the first sale forward. Reversed, the signed diff was always
            // negative, max(1, …) pinned it to one month, and every product's
            // average monthly movement read as its entire lifetime sales.
            $monthsActive = max(1, (int) $firstSale->diffInMonths(now()));
        }

        $avgMonthlyMovement = round($totalUnitsSold / $monthsActive, 1);

        // Profit margin
        $margin = 0;
        if ($this->product->selling_price > 0 && $this->product->cost_price > 0) {
            $margin = round((($this->product->selling_price - $this->product->cost_price) / $this->product->selling_price) * 100, 1);
        }

        // POS Receipts containing this product
        $transactionIds = POSTransactionItem::where('item_type', 'product')
            ->where('item_id', $this->product->id)
            ->pluck('pos_transaction_id')
            ->unique();

        $salesReceipts = POSTransaction::whereIn('id', $transactionIds)
            ->with(['participant.person', 'processedBy', 'items', 'invoice'])
            ->orderByDesc('created_at')
            ->limit(50)
            ->get();

        return view('livewire.inventory.product-show', [
            'levels' => $levels,
            'totalOnHand' => $totalOnHand,
            'totalReserved' => $totalReserved,
            'totalAvailable' => $totalAvailable,
            'movements' => $movements,
            'totalIn' => $totalIn,
            'totalSold' => $totalUnitsSold,
            'totalRevenue' => $totalRevenue,
            'totalCollected' => $totalCollected,
            'collectedPercent' => $collectedPercent,
            'avgMonthlyMovement' => $avgMonthlyMovement,
            'margin' => $margin,
            'salesReceipts' => $salesReceipts,
        ]);
    }
}
