<?php

namespace App\Http\Controllers;

use App\Models\Sale;
use App\Support\SaleFulfillment;
use App\Support\SaleType;
use Illuminate\Http\Request;
use Inertia\Inertia;
use Inertia\Response;

class SaleExchangeController extends Controller
{
    private const PER_PAGE_OPTIONS = [5, 10, 25, 50];

    public function index(Request $request): Response
    {
        $perPage = $request->integer('per_page', 10);
        if (! in_array($perPage, self::PER_PAGE_OPTIONS, true)) {
            $perPage = 10;
        }

        $exchanges = Sale::query()
            ->where('type', SaleType::EXCHANGE)
            ->with([
                'customer:id,full_name',
                'order:id,order_number',
                'relatedSale:id,sale_number',
                'items.product:id,name',
            ])
            ->withCount('items')
            ->orderByDesc('sold_at')
            ->orderByDesc('id')
            ->paginate($perPage)
            ->withQueryString();

        $returnSales = Sale::query()
            ->where('type', SaleType::RETURN)
            ->whereIn(
                'exchange_group_id',
                collect($exchanges->items())->pluck('exchange_group_id')->filter()->unique()->values(),
            )
            ->with('packs.product.unit:id,name')
            ->get()
            ->keyBy('exchange_group_id');

        $exchanges->through(function (Sale $sale) use ($returnSales): array {
            $row = SaleFulfillment::serializeSaleSummary($sale);

            $returnSale = $sale->exchange_group_id !== null
                ? $returnSales->get($sale->exchange_group_id)
                : null;
            $transactionLines = SaleFulfillment::serializeExchangeTransaction($returnSale, $sale);

            return [
                ...$row,
                'related_sale_number' => $sale->relatedSale?->sale_number,
                'related_sale_id' => $sale->related_sale_id,
                'item_count' => (int) $sale->items_count,
                'transaction_lines' => $transactionLines,
                'transaction_summary' => SaleFulfillment::exchangeTransactionSummary($transactionLines),
            ];
        });

        return Inertia::render('sales/exchanges/index', [
            'exchanges' => $exchanges,
            'filters' => [
                'per_page' => $perPage,
            ],
        ]);
    }

    public function show(Sale $sale): Response
    {
        if ($sale->type !== SaleType::EXCHANGE) {
            abort(404);
        }

        $sale->load([
            'customer:id,full_name,contact_number,address',
            'order:id,order_number',
            'relatedSale:id,sale_number,sold_at',
            'items.product.unit:id,name',
        ]);

        $returnSale = null;
        $returnedProducts = [];

        if ($sale->exchange_group_id !== null) {
            $returnSale = Sale::query()
                ->where('exchange_group_id', $sale->exchange_group_id)
                ->where('type', SaleType::RETURN)
                ->with('packs.product.unit:id,name')
                ->first();

            if ($returnSale !== null) {
                $returnedProducts = SaleFulfillment::returnLinesFromPacks($returnSale->packs);
            }
        }

        $transactionLines = SaleFulfillment::serializeExchangeTransaction($returnSale, $sale);

        return Inertia::render('sales/exchanges/show', [
            'exchangeSale' => [
                ...SaleFulfillment::serializeSaleSummary($sale),
                'customer_contact' => $sale->customer?->contact_number,
                'customer_address' => $sale->customer?->address,
                'related_sale_number' => $sale->relatedSale?->sale_number,
                'related_sale_id' => $sale->related_sale_id,
                'related_sale_sold_at' => $sale->relatedSale?->sold_at?->toDateString(),
                'return_sale_id' => $returnSale?->id,
                'return_sale_number' => $returnSale?->sale_number,
                'transaction_lines' => $transactionLines,
                'transaction_summary' => SaleFulfillment::exchangeTransactionSummary($transactionLines),
                'replacement_products' => $sale->items
                    ->map(fn ($item): array => SaleFulfillment::serializeItem($item))
                    ->values()
                    ->all(),
                'returned_products' => $returnedProducts,
            ],
        ]);
    }
}
