<?php
/**
 * Vendors — thin CRUD over rsflow's `vendors` table. Note the odd column
 * naming: rsflow prefixes every column with `vendor_` (vendor_name, vendor_tin,
 * etc). Kept as-is to avoid a schema migration and to stay compatible with any
 * other rsflow code paths that might touch this table.
 */
class Vendors extends Model
{
    private function s($v): string { return trim((string)$v); }

    public function listPaginated(int $page, int $perPage, array $filters = []): array
    {
        $where  = ['v.deleted = 0'];
        $params = [];

        if (!empty($filters['q'])) {
            $where[] = '(v.vendor_name LIKE :q OR v.vendor_no LIKE :q OR v.vendor_tin LIKE :q OR v.vendor_city LIKE :q OR v.vendor_category LIKE :q)';
            $params[':q'] = '%' . $filters['q'] . '%';
        }
        if (!empty($filters['category'])) { $where[] = 'v.vendor_category = :cat'; $params[':cat'] = $this->s($filters['category']); }

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

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

        $page    = max(1, $page);
        $perPage = max(1, min(200, $perPage));
        $offset  = ($page - 1) * $perPage;

        $rows = $db->mySelect(
            "SELECT c0d, vendor_no, vendor_name, vendor_category, vendor_tin, vendor_vrn,
                    vendor_phone_1, vendor_email, vendor_city
               FROM vendors v
              WHERE $whereSql
           ORDER BY vendor_name ASC
              LIMIT $perPage OFFSET $offset",
            $params
        ) ?: [];

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

    public function allActive(): array
    {
        return (new DB())->mySelect(
            "SELECT c0d, vendor_name, vendor_category FROM vendors WHERE deleted = 0 ORDER BY vendor_name ASC", []
        ) ?: [];
    }

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

    public function nextVendorNo(): string
    {
        $rs = (new DB())->mySelect(
            "SELECT vendor_no FROM vendors WHERE vendor_no REGEXP '^[0-9]+$' ORDER BY CAST(vendor_no AS UNSIGNED) DESC LIMIT 1", []
        );
        $last = (int)($rs[0]['vendor_no'] ?? 0);
        return str_pad((string)($last + 1), 5, '0', STR_PAD_LEFT);
    }

    public function create(array $d, int $uid): array
    {
        $name = $this->s($d['vendor_name'] ?? '');
        if ($name === '') return ['ok' => false, 'msg' => 'Vendor name is required.', 'id' => 0];

        $r = (new DB())->insertUpdate(
            "INSERT INTO vendors
                (vendor_no, vendor_name, vendor_address, vendor_phone_1, vendor_phone_2,
                 vendor_email, vendor_website, vendor_po_box, vendor_city, vendor_country,
                 vendor_tin, vendor_vrn, vendor_category, created_by, edited_by)
             VALUES
                (:vn, :nm, :ad, :p1, :p2, :em, :ws, :pb, :ci, :co, :tin, :vrn, :cat, :uid, :uid)",
            [
                ':vn'  => $this->nextVendorNo(),
                ':nm'  => $name,
                ':ad'  => $this->s($d['vendor_address'] ?? ''),
                ':p1'  => $this->s($d['vendor_phone_1'] ?? ''),
                ':p2'  => $this->s($d['vendor_phone_2'] ?? ''),
                ':em'  => $this->s($d['vendor_email']   ?? ''),
                ':ws'  => $this->s($d['vendor_website'] ?? ''),
                ':pb'  => $this->s($d['vendor_po_box']  ?? ''),
                ':ci'  => $this->s($d['vendor_city']    ?? ''),
                ':co'  => $this->s(($d['vendor_country'] ?? '') ?: 'TANZANIA'),
                ':tin' => $this->s($d['vendor_tin']     ?? ''),
                ':vrn' => $this->s($d['vendor_vrn']     ?? ''),
                ':cat' => $this->s($d['vendor_category']?? ''),
                ':uid' => $uid,
            ]
        );
        return ['ok' => $r['success'] > 0, 'msg' => $r['success'] > 0 ? 'Vendor added.' : 'Save failed.', 'id' => (int)$r['last_id']];
    }

    public function update(int $id, array $d, int $uid): array
    {
        if (!$this->byId($id)) return ['ok' => false, 'msg' => 'Vendor not found.', 'id' => 0];
        $name = $this->s($d['vendor_name'] ?? '');
        if ($name === '') return ['ok' => false, 'msg' => 'Vendor name is required.', 'id' => 0];

        (new DB())->insertUpdate(
            "UPDATE vendors SET
                vendor_name = :nm, vendor_address = :ad, vendor_phone_1 = :p1, vendor_phone_2 = :p2,
                vendor_email = :em, vendor_website = :ws, vendor_po_box = :pb, vendor_city = :ci,
                vendor_country = :co, vendor_tin = :tin, vendor_vrn = :vrn, vendor_category = :cat,
                edited_by = :uid
              WHERE c0d = :id AND deleted = 0",
            [
                ':nm' => $name,
                ':ad' => $this->s($d['vendor_address']  ?? ''),
                ':p1' => $this->s($d['vendor_phone_1']  ?? ''),
                ':p2' => $this->s($d['vendor_phone_2']  ?? ''),
                ':em' => $this->s($d['vendor_email']    ?? ''),
                ':ws' => $this->s($d['vendor_website']  ?? ''),
                ':pb' => $this->s($d['vendor_po_box']   ?? ''),
                ':ci' => $this->s($d['vendor_city']     ?? ''),
                ':co' => $this->s(($d['vendor_country'] ?? '') ?: 'TANZANIA'),
                ':tin'=> $this->s($d['vendor_tin']      ?? ''),
                ':vrn'=> $this->s($d['vendor_vrn']      ?? ''),
                ':cat'=> $this->s($d['vendor_category'] ?? ''),
                ':uid'=> $uid,
                ':id' => $id,
            ]
        );
        return ['ok' => true, 'msg' => 'Vendor updated.', 'id' => $id];
    }

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