<?php
/**
 * PmTemplates — reusable preventive-maintenance definitions.
 *
 * A template captures "how often" (interval_km AND/OR interval_days) plus
 * warning windows (threshold_km / threshold_days), typical cost and
 * priority. A template can then be assigned to N trucks via
 * truck_pm_schedules.
 *
 * The kind field is a hint for reporting/grouping — the interval fields
 * are what actually drive the schedule.
 *
 * (Iter 4 Turn 2 — Fleet PM. Replaces the rsflow asset-checklist model of
 * the same name; the underlying pm_templates table was never imported.)
 */
class PmTemplates extends Model
{
    private function s($v): string { return trim((string)$v); }
    private function nn(int $v): ?int { return $v > 0 ? $v : null; }

    public function listAll(bool $activeOnly = false): array
    {
        $where = 'deleted = 0 AND tenant_id = :tenant';
        if ($activeOnly) $where .= ' AND active = 1';
        return (new DB())->mySelect(
            "SELECT c0d, name, kind, interval_km, interval_days, threshold_km, threshold_days,
                    priority, default_labour_hours, default_parts_cost, active, notes
               FROM pm_templates
              WHERE $where
           ORDER BY active DESC, FIELD(priority,'critical','high','normal','low'), name ASC",
            [':tenant' => defined('DEFAULT_TENANT_ID') ? DEFAULT_TENANT_ID : 1]
        ) ?: [];
    }

    public function byId(int $id): array
    {
        $rs = (new DB())->mySelect(
            "SELECT * FROM pm_templates WHERE c0d = :id AND deleted = 0 LIMIT 1",
            [':id' => $id]
        );
        return $rs[0] ?? [];
    }

    public function create(array $d, int $uid): array
    {
        $name = $this->s($d['name'] ?? '');
        if ($name === '') return ['ok' => false, 'msg' => 'Template name is required.', 'id' => 0];
        $km   = $this->nn((int)($d['interval_km']   ?? 0));
        $days = $this->nn((int)($d['interval_days'] ?? 0));
        if (!$km && !$days) return ['ok' => false, 'msg' => 'Either an odometer interval OR a calendar interval is required (or both).', 'id' => 0];

        $r = (new DB())->insertUpdate(
            "INSERT INTO pm_templates
                (tenant_id, name, kind, interval_km, interval_days, threshold_km, threshold_days,
                 priority, default_labour_hours, default_parts_cost, active, notes, created_by, created_on)
             VALUES
                (:tenant, :name, :kind, :ikm, :idays, :tkm, :tdays,
                 :pri, :lab, :cost, :ac, :notes, :uid, NOW())",
            [
                ':tenant' => defined('DEFAULT_TENANT_ID') ? DEFAULT_TENANT_ID : 1,
                ':name'   => $name,
                ':kind'   => $this->s(($d['kind'] ?? '') ?: 'other'),
                ':ikm'    => $km,
                ':idays'  => $days,
                ':tkm'    => max(0, (int)($d['threshold_km']   ?? 500)),
                ':tdays'  => max(0, (int)($d['threshold_days'] ?? 7)),
                ':pri'    => $this->s(($d['priority'] ?? '') ?: 'normal'),
                ':lab'    => is_numeric($d['default_labour_hours'] ?? null) ? (float)$d['default_labour_hours'] : null,
                ':cost'   => is_numeric($d['default_parts_cost']   ?? null) ? (float)$d['default_parts_cost']   : null,
                ':ac'     => isset($d['active']) ? (int)!!$d['active'] : 1,
                ':notes'  => $this->s($d['notes'] ?? ''),
                ':uid'    => $uid,
            ]
        );
        return ['ok' => $r['success'] > 0, 'msg' => 'Template created.', 'id' => (int)$r['last_id']];
    }

    public function update(int $id, array $d, int $uid): array
    {
        $existing = $this->byId($id);
        if (!$existing) return ['ok' => false, 'msg' => 'Template not found.'];

        (new DB())->insertUpdate(
            "UPDATE pm_templates SET
                name = :name, kind = :kind,
                interval_km = :ikm, interval_days = :idays,
                threshold_km = :tkm, threshold_days = :tdays,
                priority = :pri,
                default_labour_hours = :lab, default_parts_cost = :cost,
                active = :ac, notes = :notes,
                edited_by = :uid, edited_on = NOW()
              WHERE c0d = :id AND deleted = 0",
            [
                ':name' => $this->s($d['name'] ?? ''),
                ':kind' => $this->s(($d['kind'] ?? '') ?: 'other'),
                ':ikm'  => $this->nn((int)($d['interval_km']   ?? 0)),
                ':idays'=> $this->nn((int)($d['interval_days'] ?? 0)),
                ':tkm'  => max(0, (int)($d['threshold_km']   ?? 500)),
                ':tdays'=> max(0, (int)($d['threshold_days'] ?? 7)),
                ':pri'  => $this->s(($d['priority'] ?? '') ?: 'normal'),
                ':lab'  => is_numeric($d['default_labour_hours'] ?? null) ? (float)$d['default_labour_hours'] : null,
                ':cost' => is_numeric($d['default_parts_cost']   ?? null) ? (float)$d['default_parts_cost']   : null,
                ':ac'   => isset($d['active']) ? (int)!!$d['active'] : 1,
                ':notes'=> $this->s($d['notes'] ?? ''),
                ':uid'  => $uid, ':id' => $id,
            ]
        );
        return ['ok' => true, 'msg' => 'Template updated.'];
    }

    public function toggleActive(int $id, int $uid): void
    {
        (new DB())->insertUpdate(
            "UPDATE pm_templates SET active = 1 - active, edited_by = :uid, edited_on = NOW() WHERE c0d = :id",
            [':uid' => $uid, ':id' => $id]
        );
    }

    public function softDelete(int $id, int $uid): void
    {
        (new DB())->insertUpdate(
            "UPDATE pm_templates SET deleted = 1, edited_by = :uid, edited_on = NOW() WHERE c0d = :id",
            [':uid' => $uid, ':id' => $id]
        );
    }
}
