<?php
/**
 * AssetTypes — Slice 8S-1 · Services Master Data
 *
 * Class of equipment maintained across all Service projects (Generator, AC, UPS, etc.).
 * Setup once per company; reused everywhere as the join key for pm_templates + service_packs
 * + spare_parts + callout_resolution_templates.
 */
class AssetTypes extends Model
{
    public function all(bool $activeOnly = false): array
    {
        $db = new DB();
        $where = $activeOnly ? "WHERE is_active = 1" : '';
        return $db->mySelect(
            "SELECT c0d, code, name, description, icon, is_active,
                    (SELECT COUNT(*) FROM pm_templates    WHERE asset_type_id = a.c0d AND is_active = 1) AS template_count,
                    (SELECT COUNT(*) FROM service_packs   WHERE asset_type_id = a.c0d AND is_active = 1) AS pack_count,
                    (SELECT COUNT(*) FROM spare_parts     WHERE asset_type_id = a.c0d AND is_active = 1) AS parts_count
               FROM asset_types a
              $where
              ORDER BY code",
            []
        ) ?: [];
    }

    public function find(int $id): array
    {
        $db = new DB();
        $r = $db->mySelect("SELECT * FROM asset_types WHERE c0d = :id", [':id' => $id]);
        return $r[0] ?? [];
    }

    public function save(array $d, int $uid): int
    {
        $code = strtoupper(trim((string)($d['code'] ?? '')));
        $name = trim((string)($d['name'] ?? ''));
        if ($code === '' || $name === '') throw new InvalidArgumentException('Code + name required.');
        if (!preg_match('/^[A-Z0-9_]{2,32}$/', $code)) throw new InvalidArgumentException('Code must be 2-32 chars, A-Z/0-9/_.');

        $db = new DB();
        $id = (int)($d['c0d'] ?? 0);
        if ($id > 0) {
            $db->insertUpdate(
                "UPDATE asset_types SET code=:c, name=:n, description=:d, icon=:i, is_active=:a WHERE c0d=:id",
                [':c'=>$code, ':n'=>$name, ':d'=>trim((string)($d['description'] ?? '')) ?: null,
                 ':i'=>trim((string)($d['icon'] ?? '')) ?: null, ':a'=>!empty($d['is_active']) ? 1 : 0,
                 ':id'=>$id]
            );
            return $id;
        }
        $fb = $db->insertUpdate(
            "INSERT INTO asset_types (code, name, description, icon, is_active, created_by)
             VALUES (:c, :n, :d, :i, 1, :u)",
            [':c'=>$code, ':n'=>$name, ':d'=>trim((string)($d['description'] ?? '')) ?: null,
             ':i'=>trim((string)($d['icon'] ?? '')) ?: null, ':u'=>$uid]
        );
        return (int)($fb['last_id'] ?? 0);
    }

    public function delete(int $id): void
    {
        $db = new DB();
        // Guard: don't delete if referenced by templates / packs / parts
        $counts = $db->mySelect(
            "SELECT
                (SELECT COUNT(*) FROM pm_templates  WHERE asset_type_id = :id) AS tp,
                (SELECT COUNT(*) FROM service_packs WHERE asset_type_id = :id) AS pk,
                (SELECT COUNT(*) FROM spare_parts   WHERE asset_type_id = :id) AS pt",
            [':id' => $id]
        );
        if (!empty($counts) && (int)$counts[0]['tp'] + (int)$counts[0]['pk'] + (int)$counts[0]['pt'] > 0) {
            throw new RuntimeException('Cannot delete — asset type is referenced by templates, packs, or parts. Deactivate instead.');
        }
        $db->insertUpdate("DELETE FROM asset_types WHERE c0d = :id", [':id' => $id]);
    }
}
