<?php
/**
 * ServiceContractTemplateBindings · Slice 8Z-y.
 *
 * The coverage matrix: which templates apply to which equipment class on a
 * specific service contract. Feeds PM schedule generation and drives the
 * FS visit-planning inbox.
 *
 * Auto-suggest logic uses the seeded templates catalog: a GEN 20-40kVA class
 * gets suggested every template whose scope='GEN' or scope='SITE'. PM keeps
 * / removes to taste.
 */
class ServiceContractTemplateBindings extends Model
{
    /**
     * List all bindings for a contract, joined with the template metadata so
     * the view can render slug + label + cadence + item_count without a second query.
     */
    public function listFor(int $contractId): array
    {
        $db = new DB();
        return $db->mySelect(
            "SELECT b.*,
                    t.slug, t.label AS template_label, t.category AS template_category,
                    t.scope AS template_scope, t.cadence_note, t.item_count
               FROM service_contract_template_bindings b
               JOIN service_templates_catalog t ON t.c0d = b.template_id
              WHERE b.contract_id = :c
              ORDER BY b.sort_order, b.equipment_class, b.c0d",
            [':c' => $contractId]
        ) ?: [];
    }

    /** Upsert one binding row. */
    public function save(int $contractId, array $d, int $userId): array
    {
        if ($contractId <= 0) return ['ok' => false, 'msg' => 'contract_id required.'];
        $equipClass = trim((string)($d['equipment_class'] ?? ''));
        if ($equipClass === '') return ['ok' => false, 'msg' => 'equipment_class required.'];
        $tid = (int)($d['template_id'] ?? 0);
        if ($tid <= 0) return ['ok' => false, 'msg' => 'template_id required.'];

        $params = [
            ':c'    => $contractId,
            ':eq'   => $equipClass,
            ':qty'  => (isset($d['equipment_qty']) && $d['equipment_qty'] !== '') ? (int)$d['equipment_qty'] : null,
            ':tid'  => $tid,
            ':cad'  => (isset($d['cadence_override_days']) && $d['cadence_override_days'] !== '') ? (int)$d['cadence_override_days'] : null,
            ':nt'   => trim((string)($d['notes'] ?? '')) ?: null,
            ':so'   => (int)($d['sort_order'] ?? 100),
        ];

        $db = new DB();
        $id = (int)($d['c0d'] ?? 0);
        if ($id > 0) {
            // UPDATE — drop the seeded contract_id since UPDATE uses c0d only, then re-add fields.
            $u = [
                ':eq'  => $params[':eq'],
                ':qty' => $params[':qty'],
                ':tid' => $params[':tid'],
                ':cad' => $params[':cad'],
                ':nt'  => $params[':nt'],
                ':so'  => $params[':so'],
                ':eb'  => $userId,
                ':id'  => $id,
            ];
            $db->insertUpdate(
                "UPDATE service_contract_template_bindings
                    SET equipment_class = :eq, equipment_qty = :qty, template_id = :tid,
                        cadence_override_days = :cad, notes = :nt, sort_order = :so,
                        edited_by = :eb, edited_on = NOW()
                  WHERE c0d = :id",
                $u
            );
            return ['ok' => true, 'id' => $id];
        }
        $params[':cb'] = $userId;
        $r = $db->insertUpdate(
            "INSERT INTO service_contract_template_bindings
                (contract_id, equipment_class, equipment_qty, template_id, cadence_override_days,
                 notes, sort_order, created_by, created_on)
             VALUES (:c, :eq, :qty, :tid, :cad, :nt, :so, :cb, NOW())",
            $params
        );
        return ['ok' => true, 'id' => (int)($r['last_id'] ?? 0)];
    }

    public function remove(int $id): array
    {
        if ($id <= 0) return ['ok' => false, 'msg' => 'id required.'];
        $db = new DB();
        $db->insertUpdate("DELETE FROM service_contract_template_bindings WHERE c0d = :id", [':id' => $id]);
        return ['ok' => true];
    }

    /**
     * Auto-suggest templates for a given equipment class based on the templates
     * catalog scope. Returns list of matched template rows the PM can bulk-add.
     * Matching rules:
     *   - If class starts with 'GEN' → templates with scope='GEN' or 'SITE'
     *   - If class starts with 'AC'  → scope='AC' or 'SITE'
     *   - If class starts with 'UPS' or 'BATT' → scope='BATTERY' or 'SITE'
     *   - Shelter → SHELTER + SITE
     *   - Fallback → all templates
     */
    public function suggestDefaults(int $contractId, string $equipmentClass, ?int $qty = null, int $userId = 0): array
    {
        $db = new DB();
        $upper = strtoupper($equipmentClass);
        $scopes = ['SITE']; // always include site-scope defaults
        if (strpos($upper, 'GEN') === 0) $scopes[] = 'GEN';
        elseif (strpos($upper, 'AC') === 0) $scopes[] = 'AC';
        elseif (strpos($upper, 'UPS') === 0 || strpos($upper, 'BATT') === 0) $scopes[] = 'BATTERY';
        elseif (strpos($upper, 'SHELTER') === 0) $scopes[] = 'SHELTER';
        elseif (strpos($upper, 'CALLOUT') === 0) { $scopes = ['GENERIC']; }
        // Convert scopes to SQL IN clause
        $inPh = [];
        $params = [];
        foreach ($scopes as $i => $s) { $ph = ':s' . $i; $inPh[] = $ph; $params[$ph] = $s; }
        $rows = $db->mySelect(
            "SELECT * FROM service_templates_catalog
              WHERE is_active = 1 AND scope IN (" . implode(',', $inPh) . ")
              ORDER BY FIELD(category,'PM_MONTHLY','PM_QUARTERLY','PM_SEMI_ANNUAL','PM_ANNUAL','PM_ASSET','PM_FUELTEST','CALLOUT','CALLOUT_RESOLUTION'), sort_order",
            $params
        ) ?: [];

        // Insert one binding per suggested template — skip if the same
        // (contract, equipment_class, template_id) already exists.
        $added = 0; $skipped = 0;
        foreach ($rows as $r) {
            $ex = $db->mySelect(
                "SELECT c0d FROM service_contract_template_bindings
                  WHERE contract_id = :c AND equipment_class = :eq AND template_id = :t",
                [':c' => $contractId, ':eq' => $equipmentClass, ':t' => (int)$r['c0d']]
            );
            if (!empty($ex)) { $skipped++; continue; }
            $db->insertUpdate(
                "INSERT INTO service_contract_template_bindings
                    (contract_id, equipment_class, equipment_qty, template_id, sort_order, created_by, created_on)
                 VALUES (:c, :eq, :qty, :t, :so, :cb, NOW())",
                [
                    ':c'   => $contractId,
                    ':eq'  => $equipmentClass,
                    ':qty' => $qty,
                    ':t'   => (int)$r['c0d'],
                    ':so'  => (int)$r['sort_order'],
                    ':cb'  => $userId,
                ]
            );
            $added++;
        }
        return ['ok' => true, 'added' => $added, 'skipped' => $skipped, 'scopes' => $scopes];
    }
}
