<?php
/**
 * PricingDefaults · single-row org-wide defaults for new pricing versions (Slice 8R).
 * TenderPricing::createVersion consults these when no override is supplied.
 * Edited by CRM / Finance Manager / Executive / Administrator.
 */
class PricingDefaults extends Model
{
    /** Hardcoded fallbacks used if the settings row is somehow missing. */
    public const FALLBACK = [
        'default_markup_pct'            => 20.000,
        'default_contingency_pct'       => 2.000,
        'default_vat_pct'               => 18.000,
        'default_prelims_amount'        => 0.00,
        'default_currency'              => 'TZS',
        'default_procurement_mode'      => 'LOCAL',
        'default_client_boq_visibility' => 'ITEMS_AND_SECTIONS',
    ];

    /** Fetch the single settings row. Returns fallbacks if the row is missing. */
    public function get(): array
    {
        $db = new DB();
        $r = $db->mySelect("SELECT * FROM pricing_defaults WHERE c0d = 1", []);
        if (empty($r)) return self::FALLBACK;
        return [
            'default_markup_pct'            => (float)$r[0]['default_markup_pct'],
            'default_contingency_pct'       => (float)$r[0]['default_contingency_pct'],
            'default_vat_pct'               => (float)$r[0]['default_vat_pct'],
            'default_prelims_amount'        => (float)$r[0]['default_prelims_amount'],
            'default_currency'              => (string)$r[0]['default_currency'],
            'default_procurement_mode'      => (string)($r[0]['default_procurement_mode']      ?? 'LOCAL'),
            'default_client_boq_visibility' => (string)($r[0]['default_client_boq_visibility'] ?? 'ITEMS_AND_SECTIONS'),
            'notes'                         => (string)($r[0]['notes'] ?? ''),
            'edited_by'                     => $r[0]['edited_by'] !== null ? (int)$r[0]['edited_by'] : null,
            'edited_by_name'                => (string)($r[0]['edited_by_name'] ?? ''),
            'edited_on'                     => $r[0]['edited_on'],
        ];
    }

    /**
     * Save the settings row (idempotent — always row id=1). Basic sanity guards:
     *   markup, contingency, VAT must be in [0, 500].
     *   prelims must be ≥ 0.
     *   currency must be non-empty ≤ 6 chars.
     */
    public function save(array $d, int $userId, string $userName): array
    {
        $mk  = (float)($d['default_markup_pct']      ?? 0);
        $co  = (float)($d['default_contingency_pct'] ?? 0);
        $vat = (float)($d['default_vat_pct']         ?? 0);
        $pr  = (float)($d['default_prelims_amount']  ?? 0);
        $cur = strtoupper(trim((string)($d['default_currency'] ?? 'TZS')));
        $notes = (string)($d['notes'] ?? '');

        if ($mk  < 0 || $mk  > 500) return ['ok' => false, 'msg' => 'Markup % must be between 0 and 500.'];
        if ($co  < 0 || $co  > 500) return ['ok' => false, 'msg' => 'Contingency % must be between 0 and 500.'];
        if ($vat < 0 || $vat > 500) return ['ok' => false, 'msg' => 'VAT % must be between 0 and 500.'];
        if ($pr  < 0)               return ['ok' => false, 'msg' => 'Prelims amount cannot be negative.'];
        if ($cur === '' || strlen($cur) > 6) return ['ok' => false, 'msg' => 'Currency must be 1–6 characters.'];

        // Slice 8S: procurement_mode + client_boq_visibility defaults
        $procMode = strtoupper((string)($d['default_procurement_mode'] ?? 'LOCAL'));
        if (!in_array($procMode, ['LOCAL','IMPORT','MIXED','NA'], true)) $procMode = 'LOCAL';
        $boqVis = strtoupper((string)($d['default_client_boq_visibility'] ?? 'ITEMS_AND_SECTIONS'));
        if (!in_array($boqVis, ['LUMPSUM_ONLY','ITEMS_ONLY','ITEMS_AND_SECTIONS'], true)) $boqVis = 'ITEMS_AND_SECTIONS';

        $db = new DB();
        // Upsert row 1 — the schema seeded it, but defend against manual deletion.
        $db->insertUpdate(
            "INSERT INTO pricing_defaults
                (c0d, default_markup_pct, default_contingency_pct, default_vat_pct,
                 default_prelims_amount, default_currency, default_procurement_mode, default_client_boq_visibility, notes,
                 edited_by, edited_by_name, edited_on)
             VALUES
                (1, :mk, :co, :vat, :pr, :cur, :pmo, :cbv, :nt, :u, :un, NOW())
             ON DUPLICATE KEY UPDATE
                default_markup_pct = VALUES(default_markup_pct),
                default_contingency_pct = VALUES(default_contingency_pct),
                default_vat_pct = VALUES(default_vat_pct),
                default_prelims_amount = VALUES(default_prelims_amount),
                default_currency = VALUES(default_currency),
                default_procurement_mode = VALUES(default_procurement_mode),
                default_client_boq_visibility = VALUES(default_client_boq_visibility),
                notes = VALUES(notes),
                edited_by = VALUES(edited_by),
                edited_by_name = VALUES(edited_by_name),
                edited_on = VALUES(edited_on)",
            [
                ':mk'  => $mk, ':co' => $co, ':vat' => $vat, ':pr' => $pr, ':cur' => $cur,
                ':pmo' => $procMode, ':cbv' => $boqVis,
                ':nt'  => $notes, ':u' => $userId, ':un' => $userName,
            ]
        );
        return ['ok' => true];
    }
}
