<?php
namespace App\Repositories;

use App\Database\Connection;
use App\Models\CommissionRule;
use PDO;

class CommissionRuleRepository
{
    private $db;

    public function __construct(Connection $db)
    {
        $this->db = $db;
    }

    public function getDb(): Connection
    {
        return $this->db;
    }

    public function getAll(array $filters = []): array
    {
        $sql = "SELECT * FROM commission_rules WHERE 1=1";
        $params = [];

        if (!empty($filters['status'])) {
            $sql .= " AND status = ?";
            $params[] = (string)$filters['status'];
        }
        if (!empty($filters['kpi_source'])) {
            $sql .= " AND kpi_source = ?";
            $params[] = (string)$filters['kpi_source'];
        }

        $sql .= " ORDER BY updated_at DESC, id DESC";
        $stmt = $this->db->getPdo()->prepare($sql);
        $stmt->execute($params);
        $rows = $stmt->fetchAll(PDO::FETCH_ASSOC) ?: [];
        return array_map(static function ($row) {
            return new CommissionRule($row);
        }, $rows);
    }

    public function findById(int $id): ?CommissionRule
    {
        if ($id <= 0) {
            return null;
        }
        $stmt = $this->db->getPdo()->prepare("SELECT * FROM commission_rules WHERE id = ? LIMIT 1");
        $stmt->execute([$id]);
        $row = $stmt->fetch(PDO::FETCH_ASSOC);
        return $row ? new CommissionRule($row) : null;
    }

    public function findActiveByKpiSource(string $kpiSource): array
    {
        $stmt = $this->db->getPdo()->prepare("
            SELECT *
            FROM commission_rules
            WHERE status = 'active'
              AND kpi_source = ?
            ORDER BY kpi_min_threshold ASC, id DESC
        ");
        $stmt->execute([trim($kpiSource)]);
        $rows = $stmt->fetchAll(PDO::FETCH_ASSOC) ?: [];
        return array_map(static function ($row) {
            return new CommissionRule($row);
        }, $rows);
    }

    public function save(CommissionRule $rule): int
    {
        $pdo = $this->db->getPdo();

        if (!empty($rule->id)) {
            $stmt = $pdo->prepare("
                UPDATE commission_rules
                SET title = ?,
                    kpi_source = ?,
                    target_users = ?,
                    requested_services = ?,
                    kpi_min_threshold = ?,
                    kpi_max_threshold = ?,
                    base_amount = ?,
                    reward_percentage = ?,
                    status = ?
                WHERE id = ?
            ");
            $stmt->execute([
                trim((string)$rule->title),
                trim((string)$rule->kpi_source),
                is_array($rule->target_users) ? json_encode($rule->target_users, JSON_UNESCAPED_UNICODE) : (string)$rule->target_users,
                is_array($rule->requested_services) ? json_encode($rule->requested_services, JSON_UNESCAPED_UNICODE) : (string)$rule->requested_services,
                (float)$rule->kpi_min_threshold,
                (float)$rule->kpi_max_threshold,
                (float)$rule->base_amount,
                (float)$rule->reward_percentage,
                trim((string)$rule->status) ?: 'active',
                (int)$rule->id,
            ]);
            return (int)$rule->id;
        }

        $stmt = $pdo->prepare("
            INSERT INTO commission_rules
                (title, kpi_source, target_users, requested_services, kpi_min_threshold, kpi_max_threshold, base_amount, reward_percentage, status)
            VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
        ");
        $stmt->execute([
            trim((string)$rule->title),
            trim((string)$rule->kpi_source),
            is_array($rule->target_users) ? json_encode($rule->target_users, JSON_UNESCAPED_UNICODE) : (string)$rule->target_users,
            is_array($rule->requested_services) ? json_encode($rule->requested_services, JSON_UNESCAPED_UNICODE) : (string)$rule->requested_services,
            (float)$rule->kpi_min_threshold,
            (float)$rule->kpi_max_threshold,
            (float)$rule->base_amount,
            (float)$rule->reward_percentage,
            trim((string)$rule->status) ?: 'active',
        ]);
        return (int)$pdo->lastInsertId();
    }
}
