<?php
class Trucks extends Model
{
    /** Cast helper — trims strings, keeps NULLs where empty. */
    private function s($v): string { return trim((string)$v); }
    private function n($v): ?int   { $v = preg_replace('/[^0-9\-]/', '', (string)$v); return $v === '' ? null : (int)$v; }

    /**
     * Paginated + filtered list for the index view.
     * Filters:  q         → LIKE reg_no, make, model, chassis_no
     *           type_id   → truck_types.c0d
     *           status    → active | maintenance | inactive | retired
     */
    public function listPaginated(int $page, int $perPage, array $filters = []): array
    {
        $where = ['t.deleted = 0', 't.tenant_id = :tenant'];
        $params = [':tenant' => defined('DEFAULT_TENANT_ID') ? DEFAULT_TENANT_ID : 1];

        if (!empty($filters['q'])) {
            $where[] = '(t.reg_no LIKE :q OR t.make LIKE :q OR t.model LIKE :q OR t.chassis_no LIKE :q)';
            $params[':q'] = '%' . $filters['q'] . '%';
        }
        if (!empty($filters['type_id'])) {
            $where[] = 't.truck_type_id = :type_id';
            $params[':type_id'] = (int)$filters['type_id'];
        }
        if (!empty($filters['status'])) {
            $where[] = 't.status = :status';
            $params[':status'] = $this->s($filters['status']);
        }

        $whereSql = implode(' AND ', $where);
        $db = new DB();

        $countRs = $db->mySelect("SELECT COUNT(*) AS n FROM trucks t WHERE $whereSql", $params);
        $total = (int)($countRs[0]['n'] ?? 0);

        // LIMIT/OFFSET cast to int to safely interpolate.
        $page    = max(1, $page);
        $perPage = max(1, min(200, $perPage));
        $offset  = ($page - 1) * $perPage;

        $rows = $db->mySelect(
            "SELECT t.c0d, t.reg_no, t.make, t.model, t.year, t.truck_type_id,
                    tt.display_name AS type_name,
                    t.capacity_kg, t.current_odometer, t.ownership, t.status,
                    t.photo_url
               FROM trucks t
          LEFT JOIN truck_types tt ON tt.c0d = t.truck_type_id
              WHERE $whereSql
           ORDER BY t.reg_no ASC
              LIMIT $perPage OFFSET $offset",
            $params
        ) ?: [];

        return ['rows' => $rows, 'total' => $total];
    }

    public function byId(int $id): array
    {
        $db = new DB();
        $rs = $db->mySelect(
            "SELECT t.*, tt.display_name AS type_name, tt.slug AS type_slug
               FROM trucks t
          LEFT JOIN truck_types tt ON tt.c0d = t.truck_type_id
              WHERE t.c0d = :id AND t.deleted = 0
              LIMIT 1",
            [':id' => $id]
        );
        return $rs[0] ?? [];
    }

    public function regNoExists(string $regNo, int $ignoreId = 0): bool
    {
        $db = new DB();
        $rs = $db->mySelect(
            "SELECT c0d FROM trucks
              WHERE tenant_id = :t AND reg_no = :r AND deleted = 0 AND c0d <> :ignore
              LIMIT 1",
            [
                ':t'      => defined('DEFAULT_TENANT_ID') ? DEFAULT_TENANT_ID : 1,
                ':r'      => $this->s($regNo),
                ':ignore' => $ignoreId,
            ]
        );
        return !empty($rs);
    }

    public function create(array $d, int $uid): array
    {
        $reg = strtoupper($this->s($d['reg_no'] ?? ''));
        if ($reg === '') return ['ok' => false, 'msg' => 'Registration number is required.', 'id' => 0];
        if ($this->regNoExists($reg)) return ['ok' => false, 'msg' => "Registration $reg is already on file.", 'id' => 0];

        $db = new DB();
        $r  = $db->insertUpdate(
            "INSERT INTO trucks
                (tenant_id, reg_no, truck_type_id, make, model, year, chassis_no, engine_no, colour,
                 tare_kg, capacity_kg, fuel_tank_liters, current_odometer, ownership, acquired_on,
                 status, branch_id, notes, created_by, created_on)
             VALUES
                (:tenant, :reg, :type, :make, :model, :year, :chassis, :engine, :colour,
                 :tare, :cap, :fuel, :odo, :own, :acq,
                 :status, :branch, :notes, :uid, NOW())",
            [
                ':tenant'  => defined('DEFAULT_TENANT_ID') ? DEFAULT_TENANT_ID : 1,
                ':reg'     => $reg,
                ':type'    => $this->n($d['truck_type_id'] ?? null),
                ':make'    => $this->s($d['make']    ?? ''),
                ':model'   => $this->s($d['model']   ?? ''),
                ':year'    => $this->n($d['year']    ?? null),
                ':chassis' => $this->s($d['chassis_no'] ?? ''),
                ':engine'  => $this->s($d['engine_no']  ?? ''),
                ':colour'  => $this->s($d['colour']  ?? ''),
                ':tare'    => $this->n($d['tare_kg']          ?? null),
                ':cap'     => $this->n($d['capacity_kg']      ?? null),
                ':fuel'    => $this->n($d['fuel_tank_liters'] ?? null),
                ':odo'     => (int)$this->n($d['current_odometer'] ?? 0),
                ':own'     => $this->s(($d['ownership'] ?? '') ?: 'owned'),
                ':acq'     => !empty($d['acquired_on']) ? $this->s($d['acquired_on']) : null,
                ':status'  => $this->s(($d['status'] ?? '') ?: 'active'),
                ':branch'  => $this->n($d['branch_id'] ?? null),
                ':notes'   => $this->s($d['notes']  ?? ''),
                ':uid'     => $uid,
            ]
        );
        return ['ok' => $r['success'] > 0, 'msg' => $r['success'] > 0 ? 'Truck added.' : 'Save failed.', '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' => 'Truck not found.', 'id' => 0];

        $reg = strtoupper($this->s($d['reg_no'] ?? ''));
        if ($reg === '') return ['ok' => false, 'msg' => 'Registration number is required.', 'id' => 0];
        if ($this->regNoExists($reg, $id)) return ['ok' => false, 'msg' => "Registration $reg is already on another truck.", 'id' => 0];

        $db = new DB();
        $r  = $db->insertUpdate(
            "UPDATE trucks SET
                reg_no = :reg, truck_type_id = :type, make = :make, model = :model, year = :year,
                chassis_no = :chassis, engine_no = :engine, colour = :colour,
                tare_kg = :tare, capacity_kg = :cap, fuel_tank_liters = :fuel,
                current_odometer = :odo, ownership = :own, acquired_on = :acq,
                status = :status, branch_id = :branch, notes = :notes,
                edited_by = :uid, edited_on = NOW()
              WHERE c0d = :id AND deleted = 0",
            [
                ':reg'     => $reg,
                ':type'    => $this->n($d['truck_type_id'] ?? null),
                ':make'    => $this->s($d['make']  ?? ''),
                ':model'   => $this->s($d['model'] ?? ''),
                ':year'    => $this->n($d['year']  ?? null),
                ':chassis' => $this->s($d['chassis_no'] ?? ''),
                ':engine'  => $this->s($d['engine_no']  ?? ''),
                ':colour'  => $this->s($d['colour']  ?? ''),
                ':tare'    => $this->n($d['tare_kg']          ?? null),
                ':cap'     => $this->n($d['capacity_kg']      ?? null),
                ':fuel'    => $this->n($d['fuel_tank_liters'] ?? null),
                ':odo'     => (int)$this->n($d['current_odometer'] ?? 0),
                ':own'     => $this->s(($d['ownership'] ?? '') ?: 'owned'),
                ':acq'     => !empty($d['acquired_on']) ? $this->s($d['acquired_on']) : null,
                ':status'  => $this->s(($d['status'] ?? '')    ?: 'active'),
                ':branch'  => $this->n($d['branch_id'] ?? null),
                ':notes'   => $this->s($d['notes']     ?? ''),
                ':uid'     => $uid,
                ':id'      => $id,
            ]
        );
        return ['ok' => true, 'msg' => 'Truck updated.', 'id' => $id];
    }

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

    public function setPhotoUrl(int $id, string $url, int $uid): void
    {
        $db = new DB();
        $db->insertUpdate(
            "UPDATE trucks SET photo_url = :u, edited_by = :uid, edited_on = NOW() WHERE c0d = :id",
            [':u' => $url, ':uid' => $uid, ':id' => $id]
        );
    }
}
