<?php
declare(strict_types=1);

final class BuildRepository {
    public static function ensureSchema(): void {
        $pdo = Database::pdo();
        $pdo->exec(<<<'SQL'
CREATE TABLE IF NOT EXISTS builds (
    id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    build_code VARCHAR(64) NOT NULL,
    status ENUM('queued','running','passed','failed','cancelled') NOT NULL DEFAULT 'queued',
    phase VARCHAR(64) NOT NULL DEFAULT 'init',
    git_ref VARCHAR(256) NULL,
    git_sha VARCHAR(64) NULL,
    branch VARCHAR(128) NULL,
    pipeline_yaml LONGTEXT NULL,
    params_json LONGTEXT NOT NULL,
    dockerfile_version VARCHAR(32) NOT NULL DEFAULT '00.01.00.1000',
    builder_id VARCHAR(128) NOT NULL DEFAULT 'local-docker',
    version_app VARCHAR(32) NULL,
    version_code INT NULL,
    target_os VARCHAR(32) NOT NULL DEFAULT 'android',
    min_api_level INT NOT NULL DEFAULT 24,
    ota_channel VARCHAR(64) NULL,
    auto_ota TINYINT(1) NOT NULL DEFAULT 0,
    auto_deploy TINYINT(1) NOT NULL DEFAULT 0,
    log_path VARCHAR(512) NULL,
    artifacts_json LONGTEXT NULL,
    error_message VARCHAR(512) NULL,
    created_by_user_id INT UNSIGNED NULL,
    started_at TIMESTAMP NULL,
    finished_at TIMESTAMP NULL,
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    UNIQUE KEY uq_builds_code (build_code),
    KEY idx_builds_status (status),
    KEY idx_builds_created (created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
SQL);
    }

    public static function create(array $row): int {
        self::ensureSchema();
        $pdo = Database::pdo();
        $stmt = $pdo->prepare(<<<'SQL'
INSERT INTO builds (
    build_code, status, phase, git_ref, git_sha, branch, pipeline_yaml, params_json,
    dockerfile_version, builder_id, target_os, min_api_level, ota_channel, auto_ota, auto_deploy,
    log_path, created_by_user_id
) VALUES (
    :build_code, :status, :phase, :git_ref, :git_sha, :branch, :pipeline_yaml, :params_json,
    :dockerfile_version, :builder_id, :target_os, :min_api_level, :ota_channel, :auto_ota, :auto_deploy,
    :log_path, :created_by_user_id
)
SQL);
        $stmt->execute([
            ':build_code' => $row['build_code'],
            ':status' => $row['status'] ?? 'queued',
            ':phase' => $row['phase'] ?? 'queued',
            ':git_ref' => $row['git_ref'] ?? null,
            ':git_sha' => $row['git_sha'] ?? null,
            ':branch' => $row['branch'] ?? null,
            ':pipeline_yaml' => $row['pipeline_yaml'] ?? null,
            ':params_json' => $row['params_json'] ?? '{}',
            ':dockerfile_version' => $row['dockerfile_version'] ?? '00.01.00.1000',
            ':builder_id' => $row['builder_id'] ?? 'local-docker',
            ':target_os' => $row['target_os'] ?? 'android',
            ':min_api_level' => (int) ($row['min_api_level'] ?? 24),
            ':ota_channel' => $row['ota_channel'] ?? null,
            ':auto_ota' => !empty($row['auto_ota']) ? 1 : 0,
            ':auto_deploy' => !empty($row['auto_deploy']) ? 1 : 0,
            ':log_path' => $row['log_path'] ?? null,
            ':created_by_user_id' => $row['created_by_user_id'] ?? null,
        ]);
        return (int) $pdo->lastInsertId();
    }

    public static function update(int $id, array $fields): void {
        self::ensureSchema();
        $allowed = ['status', 'phase', 'version_app', 'version_code', 'artifacts_json', 'error_message', 'started_at', 'finished_at', 'git_sha', 'log_path'];
        $sets = [];
        $params = [':id' => $id];
        foreach ($fields as $k => $v) {
            if (!in_array($k, $allowed, true)) {
                continue;
            }
            $sets[] = "$k = :$k";
            $params[":$k"] = $v;
        }
        if (!$sets) {
            return;
        }
        $sql = 'UPDATE builds SET ' . implode(', ', $sets) . ' WHERE id = :id';
        Database::pdo()->prepare($sql)->execute($params);
    }

    public static function getById(int $id): ?array {
        self::ensureSchema();
        $stmt = Database::pdo()->prepare('SELECT * FROM builds WHERE id = ? LIMIT 1');
        $stmt->execute([$id]);
        $row = $stmt->fetch();
        return $row ?: null;
    }

    public static function listRecent(int $limit = 10): array {
        self::ensureSchema();
        $stmt = Database::pdo()->prepare('SELECT * FROM builds ORDER BY id DESC LIMIT ?');
        $stmt->bindValue(1, $limit, PDO::PARAM_INT);
        $stmt->execute();
        return $stmt->fetchAll() ?: [];
    }

    public static function healthSummary(): array {
        self::ensureSchema();
        BuildRunner::reconcileRunningBuilds();
        BuildRunner::reconcileQueuedBuilds();
        $pdo = Database::pdo();
        $running = (int) $pdo->query("SELECT COUNT(*) FROM builds WHERE status = 'running'")->fetchColumn();
        $failed = (int) $pdo->query("SELECT COUNT(*) FROM builds WHERE status = 'failed' AND created_at > (NOW() - INTERVAL 7 DAY)")->fetchColumn();
        $passed = (int) $pdo->query("SELECT COUNT(*) FROM builds WHERE status = 'passed' AND created_at > (NOW() - INTERVAL 7 DAY)")->fetchColumn();
        $dockerOk = BuildRunner::dockerAvailable();
        return [
            'docker' => $dockerOk ? 'ok' : 'down',
            'running' => $running,
            'passed_7d' => $passed,
            'failed_7d' => $failed,
            'ci_version' => cfg('build.ci_version', '00.01.00.1000'),
        ];
    }
}
