<?php

namespace App\Services;

use App\Helpers\AmountInWords;
use App\Helpers\CompanyMedia;
use App\Helpers\CompanySettings;
use App\Helpers\DeliveryChallanDocumentSettings;
use App\Helpers\GstHelper;
use App\Models\Company;
use App\Models\DeliveryChallan;
use App\Models\TaxRate;

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

        $settings = CompanySettings::forCompany($company->id);
        $docSettings = DeliveryChallanDocumentSettings::forCompany($company->id);
        $gstContext = GstHelper::documentViewContext($company, $challan);

        return array_merge([
            'deliveryChallan' => $challan,
            'company' => $company,
            'settings' => $settings,
            'docSettings' => $docSettings,
            'taxBreakdown' => $gstContext['gstMode']
                ? []
                : $this->buildTaxBreakdown($challan, $taxRates),
            'amountInWords' => AmountInWords::rupees((float) $challan->grand_total),
            'documentCopies' => DeliveryChallanDocumentSettings::documentCopies($company->id),
            'challanTitle' => DeliveryChallanDocumentSettings::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(DeliveryChallan $challan, $taxRates): array
    {
        $groups = [];

        foreach ($challan->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);
    }
}
