<?php

declare(strict_types=1);

namespace App\Business\Purchase;

use App\Business\Purchase\Enums\PurchaseInquiryQuoteStatus;
use App\Models\DberpPurchaseInquiryQuote;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Arr;

final class PurchaseInquiryComparisonService
{
    public function __construct(
        private readonly PurchaseOrderPriceMatchService $priceMatchService,
    ) {}

    /**
     * @param  array<string, mixed>  $filters
     * @return array{rows:list<array<string, mixed>>, totals:array<string, int|string>}
     */
    public function overview(array $filters): array
    {
        $quotes = DberpPurchaseInquiryQuote::query()
            ->with(['purchaseRequestItem.request', 'product', 'supplier'])
            ->when(Arr::get($filters, 'purchase_request_id'), fn (Builder $query, $value): Builder => $query->where('purchase_request_id', (int) $value))
            ->when(Arr::get($filters, 'product_id'), fn (Builder $query, $value): Builder => $query->where('product_id', (int) $value))
            ->when(Arr::get($filters, 'supplier_id'), fn (Builder $query, $value): Builder => $query->where('supplier_id', (int) $value))
            ->when(Arr::get($filters, 'status'), fn (Builder $query, $value): Builder => $query->where('status', (string) $value))
            ->when(Arr::get($filters, 'recommended_only'), fn (Builder $query): Builder => $query->where('is_recommended', true))
            ->when(Arr::get($filters, 'quote_date_from'), fn (Builder $query, $value): Builder => $query->whereDate('quote_date', '>=', (string) $value))
            ->when(Arr::get($filters, 'quote_date_until'), fn (Builder $query, $value): Builder => $query->whereDate('quote_date', '<=', (string) $value))
            ->when(Arr::get($filters, 'valid_until'), fn (Builder $query, $value): Builder => $query->whereDate('valid_until', '<=', (string) $value))
            ->orderByDesc('quote_date')
            ->orderByDesc('id')
            ->get();

        $rows = $quotes->map(function (DberpPurchaseInquiryQuote $quote): array {
            $context = $this->priceMatchService->resolveContext(
                productId: (int) $quote->product_id,
                supplierId: (int) $quote->supplier_id,
                purchaseRequestItemId: (int) $quote->purchase_request_item_id,
                sourceInquiryQuoteId: (int) $quote->getKey(),
            );

            $insight = $this->priceMatchService->evaluatePriceInsight((float) $quote->unit_price, $context);

            return [
                'quote_code' => $quote->code,
                'purchase_request_code' => $quote->purchase_request_code,
                'product_name' => $quote->product_name_snapshot ?: $quote->product?->name,
                'product_spec' => $quote->product_spec_snapshot ?: $quote->product?->spec_model,
                'supplier_name' => $quote->supplier_name_snapshot ?: $quote->supplier?->name,
                'unit_price' => (string) $quote->unit_price,
                'lowest_inquiry_unit_price' => $context['lowest_inquiry_unit_price'],
                'recent_supplier_transaction_unit_price' => $context['recent_supplier_transaction_unit_price'],
                'recent_product_transaction_unit_price' => $context['recent_product_transaction_unit_price'],
                'lead_time_days' => $quote->lead_time_days,
                'recent_supplier_lead_time_days' => $context['recent_supplier_lead_time_days'],
                'quote_date' => $quote->getRawOriginal('quote_date'),
                'valid_until' => $quote->getRawOriginal('valid_until'),
                'is_recommended' => (bool) $quote->is_recommended,
                'status' => $quote->status,
                'status_label' => PurchaseInquiryQuoteStatus::tryFrom((string) $quote->status)?->label() ?? (string) $quote->status,
                'comparison_label' => $insight['label'],
                'comparison_note' => $insight['summary'],
            ];
        })->values()->all();

        return [
            'rows' => $rows,
            'totals' => [
                'quote_count' => count($rows),
                'recommended_count' => count(array_filter($rows, fn (array $row): bool => (bool) $row['is_recommended'])),
                'expiring_count' => count(array_filter($rows, fn (array $row): bool => $row['status'] === PurchaseInquiryQuoteStatus::Active->value && $row['valid_until'] !== null && $row['valid_until'] <= now()->addDays(3)->toDateString())),
            ],
        ];
    }
}