<?php
declare(strict_types=1);

namespace App\Models;

use App\Core\Model;
use App\Models\AuditLogModel;
use PDO;

/**
 * Vendor Model
 */
class VendorModel extends Model
{
    protected string $table = 'vendors';
    private AuditLogModel $auditLogger;

    public function __construct()
    {
        parent::__construct();
        $this->auditLogger = new AuditLogModel();
    }

    public function getAll(int $tenantId, array $filters = [], int $page = 1, int $perPage = 20): array
    {
        $offset = ($page - 1) * $perPage;
        $sql = "SELECT * FROM vendors WHERE tenant_id = :tenant_id";
        $params = [':tenant_id' => $tenantId];

        if (!empty($filters['search'])) {
            $sql .= " AND (name LIKE :search1 OR company_name LIKE :search2 OR email LIKE :search3 OR phone LIKE :search4)";
            $params[':search1'] = '%' . $filters['search'] . '%';
            $params[':search2'] = '%' . $filters['search'] . '%';
            $params[':search3'] = '%' . $filters['search'] . '%';
            $params[':search4'] = '%' . $filters['search'] . '%';
        }

        if (!empty($filters['status']) && $filters['status'] !== 'all') {
            $sql .= " AND status = :status";
            $params[':status'] = $filters['status'];
        }

        $sort = $filters['sort'] ?? 'name';
        $order = isset($filters['order']) && strtoupper($filters['order']) === 'DESC' ? 'DESC' : 'ASC';

        $allowedSort = ['name', 'company_name', 'email', 'status', 'created_at'];
        if (!in_array($sort, $allowedSort))
            $sort = 'name';

        $sql .= " ORDER BY $sort $order LIMIT $perPage OFFSET $offset";
        $stmt = $this->db->prepare($sql);
        $stmt->execute($params);
        $vendors = $stmt->fetchAll();

        foreach ($vendors as &$v) {
            $v['outstanding_balance'] = $this->getOutstandingBalance($v['id'], $tenantId);
        }

        return $vendors;
    }

    public function getOutstandingBalance(int $id, int $tenantId): float
    {
        $stmt = $this->db->prepare("SELECT opening_balance, opening_balance_type FROM vendors WHERE id = ? AND tenant_id = ?");
        $stmt->execute([$id, $tenantId]);
        $row = $stmt->fetch();

        if (!$row) return 0.00;

        $balance = (float) $row['opening_balance'];
        return $row['opening_balance_type'] === 'credit' ? $balance : -$balance;
    }

    public function countAll(int $tenantId, array $filters = []): int
    {
        $sql = "SELECT COUNT(*) FROM vendors WHERE tenant_id = :tenant_id";
        $params = [':tenant_id' => $tenantId];
        if (!empty($filters['search'])) {
            $sql .= " AND (name LIKE :search1 OR company_name LIKE :search2)";
            $params[':search1'] = '%' . $filters['search'] . '%';
            $params[':search2'] = '%' . $filters['search'] . '%';
        }

        if (!empty($filters['status']) && $filters['status'] !== 'all') {
            $sql .= " AND status = :status";
            $params[':status'] = $filters['status'];
        }
        $stmt = $this->db->prepare($sql);
        $stmt->execute($params);
        return (int) $stmt->fetchColumn();
    }

    public function getById(int $id, int $tenantId): ?array
    {
        $sql = "SELECT * FROM vendors WHERE id = :id AND tenant_id = :tenant_id LIMIT 1";
        $stmt = $this->db->prepare($sql);
        $stmt->execute([':id' => $id, ':tenant_id' => $tenantId]);
        $vendor = $stmt->fetch();
        
        if ($vendor) {
            $vendor['outstanding_balance'] = $this->getOutstandingBalance($id, $tenantId);
        }
        
        return $vendor ?: null;
    }

    public function softDelete(int $id, int $tenantId, int $userId): bool
    {
        $old = $this->getById($id, $tenantId);
        if (!$old)
            return false;

        $stmt = $this->db->prepare("UPDATE vendors SET status = 'inactive' WHERE id = :id AND tenant_id = :tenant_id");
        $result = $stmt->execute([':id' => $id, ':tenant_id' => $tenantId]);

        if ($result) {
            $this->auditLogger->log($tenantId, $userId, 'delete', 'vendors', $id, $old, ['status' => 'inactive']);
        }

        return $result;
    }
}
