<?php
namespace App\Repositories;

use App\Database\Connection;
use App\Utils\Logger;
use PDO;
use PDOException;

class AiRepository
{
    private Connection $db;

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

    public function createRequest(array $data): int
    {
        try {
            $pdo = $this->db->getPdo();
            $stmt = $pdo->prepare("INSERT INTO ai_requests
                (user_id, user_didar_id, feature_key, entity_type, entity_id, prompt_version, model, request_status, input_summary_json, source_refs_json)
                VALUES (?, ?, ?, ?, ?, ?, ?, 'pending', ?, ?)");
            $stmt->execute([
                (int)($data['user_id'] ?? 0) ?: null,
                $this->nullableString($data['user_didar_id'] ?? null),
                $this->requiredString($data['feature_key'] ?? ''),
                $this->nullableString($data['entity_type'] ?? null),
                $this->nullableString($data['entity_id'] ?? null),
                $this->requiredString($data['prompt_version'] ?? 'v1'),
                $this->nullableString($data['model'] ?? null),
                $this->json($data['input_summary'] ?? []),
                $this->json($data['source_refs'] ?? []),
            ]);
            return (int)$pdo->lastInsertId();
        } catch (PDOException $e) {
            Logger::logError('Failed to create AI request audit row', $e, [
                'feature_key' => $data['feature_key'] ?? '',
            ]);
            throw $e;
        }
    }

    public function finishRequest(int $id, string $status, array $output = [], array $sourceRefs = [], string $errorMessage = ''): void
    {
        try {
            $stmt = $this->db->getPdo()->prepare("UPDATE ai_requests
                SET request_status = ?, output_json = ?, source_refs_json = ?, error_message = ?, completed_at = NOW()
                WHERE id = ?");
            $stmt->execute([
                $status,
                $this->json($output),
                $this->json($sourceRefs),
                $this->nullableString($errorMessage),
                $id,
            ]);
        } catch (PDOException $e) {
            Logger::logError('Failed to finish AI request audit row', $e, ['id' => $id]);
            throw $e;
        }
    }

    public function createFeedback(int $aiRequestId, int $userId, int $rating, bool $accepted, string $comment = ''): int
    {
        $rating = max(-1, min(1, $rating));
        try {
            $pdo = $this->db->getPdo();
            $stmt = $pdo->prepare("INSERT INTO ai_feedback
                (ai_request_id, user_id, rating, accepted, comment)
                VALUES (?, ?, ?, ?, ?)");
            $stmt->execute([
                $aiRequestId,
                $userId > 0 ? $userId : null,
                $rating,
                $accepted ? 1 : 0,
                $this->nullableString($comment),
            ]);
            return (int)$pdo->lastInsertId();
        } catch (PDOException $e) {
            Logger::logError('Failed to create AI feedback', $e, ['ai_request_id' => $aiRequestId]);
            throw $e;
        }
    }

    public function findRequest(int $id): ?array
    {
        $stmt = $this->db->getPdo()->prepare("SELECT * FROM ai_requests WHERE id = ? LIMIT 1");
        $stmt->execute([$id]);
        $row = $stmt->fetch(PDO::FETCH_ASSOC);
        return is_array($row) ? $row : null;
    }

    private function json($value): string
    {
        return json_encode($value, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
    }

    private function requiredString($value): string
    {
        return trim((string)$value);
    }

    private function nullableString($value): ?string
    {
        $value = trim((string)$value);
        return $value === '' ? null : $value;
    }
}
