<?php

namespace App\Services;

use App\Helpers\AmountInWords;
use App\Helpers\CompanyMedia;
use App\Helpers\CompanySettings;
use App\Helpers\PurchaseOrderDocumentSettings;
use App\Helpers\GstHelper;
use App\Models\Company;
use App\Models\PurchaseOrder;
use App\Models\TaxRate;

class PurchaseOrderDocumentPresenter
{
    /**
     * @return array<string, mixed>
     */
    public function displayData(PurchaseOrder $purchaseOrder): array
    {
        $purchaseOrder->load(['items', 'vendor']);
        $company = Company::findOrFail($purchaseOrder->company_id);
        $taxRates = TaxRate::where('company_id', $company->id)->active()->selectable()->get();

        $settings = CompanySettings::forCompany($company->id);
        $docSettings = PurchaseOrderDocumentSettings::forCompany($company->id);
        $gstContext = GstHelper::documentViewContext($company, $purchaseOrder);
        $party = $purchaseOrder->vendor;
        $shipToLines = $company->fullAddressLines();

        return array_merge([
            'purchaseOrder' => $purchaseOrder,
            'party' => $party,
            'shipToLines' => $shipToLines,
            'company' => $company,
            'settings' => $settings,
            'docSettings' => $docSettings,
            'taxBreakdown' => $gstContext['gstMode']
                ? []
                : $this->buildTaxBreakdown($purchaseOrder, $taxRates),
            'amountInWords' => AmountInWords::rupees((float) $purchaseOrder->grand_total),
            'documentCopies' => [
                'original' => 'Original Copy',
                'duplicate' => 'Duplicate Copy',
            ],
            'purchaseOrderTitle' => PurchaseOrderDocumentSettings::title($company->id),
            'logoSrc' => CompanyMedia::imageSource($company->logo_path),
            'signatureSrc' => CompanyMedia::imageSource($company->signature_image_path),
        ], $gstContext);
    }

    /**
     * @return list<array{name: string, rate: float, amount: float}>
     */
    private function buildTaxBreakdown(PurchaseOrder $purchaseOrder, $taxRates): array
    {
        $groups = [];

        foreach ($purchaseOrder->items as $line) {
            if ((float) $line->tax_amount <= 0) {
                continue;
            }

            $rate = (float) $line->tax_rate;
            $key = number_format($rate, 2, '.', '');

            if (! isset($groups[$key])) {
                $tax = $taxRates->first(fn ($t) => abs((float) $t->rate - $rate) < 0.001);
                $groups[$key] = [
                    'name' => $tax?->name ?? 'Tax',
                    'rate' => $rate,
                    'amount' => 0,
                ];
            }

            $groups[$key]['amount'] += (float) $line->tax_amount;
        }

        usort($groups, fn ($a, $b) => $a['rate'] <=> $b['rate']);

        return array_values($groups);
    }
}
