<?php
namespace App\Repositories;

use App\Database\Connection;
use PDO;

class OperationRepository
{
    private Connection $db;

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

    public function getPdo(): PDO
    {
        return $this->db->getPdo();
    }

    public function getLeadPoolByKey(string $poolKey): ?array
    {
        $stmt = $this->getPdo()->prepare("SELECT * FROM lead_pools WHERE pool_key = ? AND is_active = 1 LIMIT 1");
        $stmt->execute([$poolKey]);
        $row = $stmt->fetch(PDO::FETCH_ASSOC);
        return $row ?: null;
    }

    public function listLeadPools(): array
    {
        return $this->getPdo()->query("SELECT lp.*, COUNT(p.id) AS lead_count
            FROM lead_pools lp
            LEFT JOIN persons p ON p.lead_pool_id = lp.id
            WHERE lp.is_active = 1
            GROUP BY lp.id, lp.pool_key, lp.title, lp.description, lp.is_system, lp.is_active, lp.created_at, lp.updated_at
            ORDER BY lp.is_system DESC, lp.title ASC")->fetchAll(PDO::FETCH_ASSOC) ?: [];
    }

    public function createRun(?int $ruleId, string $runType, ?int $userId, array $filters, array $operation): int
    {
        $stmt = $this->getPdo()->prepare("INSERT INTO operation_runs
            (rule_id, run_type, status, requested_by_user_id, started_at, filter_snapshot_json, operation_snapshot_json, created_at)
            VALUES (?, ?, 'running', ?, NOW(), ?, ?, NOW())");
        $stmt->execute([
            $ruleId,
            $runType,
            $userId,
            json_encode($filters, JSON_UNESCAPED_UNICODE),
            json_encode($operation, JSON_UNESCAPED_UNICODE)
        ]);
        return (int)$this->getPdo()->lastInsertId();
    }

    public function finishRun(int $runId, string $status, int $matched, int $selected, int $affected, int $failed, string $errorSummary = ''): void
    {
        $stmt = $this->getPdo()->prepare("UPDATE operation_runs
            SET status = ?, finished_at = NOW(), matched_count = ?, selected_count = ?, affected_count = ?, failed_count = ?, error_summary = ?
            WHERE id = ?");
        $stmt->execute([$status, $matched, $selected, $affected, $failed, $errorSummary, $runId]);
    }

    public function insertRunItem(int $runId, array $item): void
    {
        $stmt = $this->getPdo()->prepare("INSERT INTO operation_run_items
            (operation_run_id, entity_type, entity_id, contact_didar_id, deal_didar_id, before_json, after_json, status, error_message, created_at)
            VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, NOW())");
        $stmt->execute([
            $runId,
            $item['entity_type'] ?? 'lead',
            $item['entity_id'] ?? null,
            $item['contact_didar_id'] ?? null,
            $item['deal_didar_id'] ?? null,
            isset($item['before']) ? json_encode($item['before'], JSON_UNESCAPED_UNICODE) : null,
            isset($item['after']) ? json_encode($item['after'], JSON_UNESCAPED_UNICODE) : null,
            $item['status'] ?? 'success',
            $item['error_message'] ?? null
        ]);
    }

    public function listRuns(int $limit = 50): array
    {
        $limit = max(1, min(200, $limit));
        return $this->getPdo()->query("SELECT r.*, rule.name AS rule_name
            FROM operation_runs r
            LEFT JOIN operation_rules rule ON rule.id = r.rule_id
            ORDER BY r.created_at DESC
            LIMIT {$limit}")->fetchAll(PDO::FETCH_ASSOC) ?: [];
    }

    public function getRun(int $id): ?array
    {
        $stmt = $this->getPdo()->prepare("SELECT * FROM operation_runs WHERE id = ?");
        $stmt->execute([$id]);
        $run = $stmt->fetch(PDO::FETCH_ASSOC);
        if (!$run) {
            return null;
        }
        $items = $this->getPdo()->prepare("SELECT * FROM operation_run_items WHERE operation_run_id = ? ORDER BY id ASC LIMIT 500");
        $items->execute([$id]);
        $run['items'] = $items->fetchAll(PDO::FETCH_ASSOC) ?: [];
        return $run;
    }
}
