<?php

declare(strict_types=1);

final class MyronTemplateChromeAssignmentRepository
{
    public function __construct(private readonly PDO $pdo)
    {
    }

    /**
     * @return array<string, mixed>|null
     */
    public function getForTemplate(string $templateId): ?array
    {
        $templateId = trim($templateId);
        if ($templateId === '') {
            return null;
        }
        $statement = $this->pdo->prepare('SELECT * FROM template_chrome_assignments WHERE template_id = :template_id LIMIT 1');
        $statement->execute([':template_id' => $templateId]);
        $row = $statement->fetch(PDO::FETCH_ASSOC);
        return is_array($row) ? $this->hydrate($row) : null;
    }

    /**
     * @return list<array<string, mixed>>
     */
    public function listAll(): array
    {
        $statement = $this->pdo->query('SELECT * FROM template_chrome_assignments ORDER BY template_id ASC');
        $rows = $statement ? $statement->fetchAll(PDO::FETCH_ASSOC) : [];
        return array_values(array_map(fn (array $row): array => $this->hydrate($row), array_filter($rows, 'is_array')));
    }

    public function setFooter(string $templateId, ?string $footerVariantId, string $userId = ''): void
    {
        $current = $this->getForTemplate($templateId) ?? [];
        $this->setForTemplate($templateId, [
            'footer_variant_id' => $footerVariantId,
            'navigation_design_id' => $current['navigation_design_id'] ?? null,
        ], $userId);
    }

    public function setNavigation(string $templateId, ?string $navigationDesignId, string $userId = ''): void
    {
        $current = $this->getForTemplate($templateId) ?? [];
        $this->setForTemplate($templateId, [
            'footer_variant_id' => $current['footer_variant_id'] ?? null,
            'navigation_design_id' => $navigationDesignId,
        ], $userId);
    }

    /**
     * @param array{footer_variant_id?:string|null,navigation_design_id?:string|null} $assignment
     */
    public function setForTemplate(string $templateId, array $assignment, string $userId = ''): void
    {
        $templateId = trim($templateId);
        if ($templateId === '') {
            throw new InvalidArgumentException('Template id is required.');
        }

        $footerVariantId = $this->nullableString($assignment['footer_variant_id'] ?? null);
        $navigationDesignId = $this->nullableString($assignment['navigation_design_id'] ?? null);
        if ($footerVariantId === null && $navigationDesignId === null) {
            $this->clearAll($templateId);
            return;
        }

        $existing = $this->getForTemplate($templateId);
        $now = myronNow();
        if (is_array($existing)) {
            $statement = $this->pdo->prepare(
                'UPDATE template_chrome_assignments
                 SET footer_variant_id = :footer_variant_id,
                     navigation_design_id = :navigation_design_id,
                     updated_by_user_id = :updated_by_user_id,
                     updated_at = :updated_at
                 WHERE template_id = :template_id'
            );
            $statement->execute([
                ':footer_variant_id' => $footerVariantId,
                ':navigation_design_id' => $navigationDesignId,
                ':updated_by_user_id' => $userId,
                ':updated_at' => $now,
                ':template_id' => $templateId,
            ]);
            return;
        }

        $statement = $this->pdo->prepare(
            'INSERT INTO template_chrome_assignments (
                id, template_id, footer_variant_id, navigation_design_id,
                created_at, updated_at, updated_by_user_id
             ) VALUES (
                :id, :template_id, :footer_variant_id, :navigation_design_id,
                :created_at, :updated_at, :updated_by_user_id
             )'
        );
        $statement->execute([
            ':id' => myronGenerateId('tca'),
            ':template_id' => $templateId,
            ':footer_variant_id' => $footerVariantId,
            ':navigation_design_id' => $navigationDesignId,
            ':created_at' => $now,
            ':updated_at' => $now,
            ':updated_by_user_id' => $userId,
        ]);
    }

    public function clearAll(string $templateId): void
    {
        $statement = $this->pdo->prepare('DELETE FROM template_chrome_assignments WHERE template_id = :template_id');
        $statement->execute([':template_id' => trim($templateId)]);
    }

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

    /**
     * @param array<string, mixed> $row
     * @return array<string, mixed>
     */
    private function hydrate(array $row): array
    {
        return [
            'id' => (string) ($row['id'] ?? ''),
            'template_id' => (string) ($row['template_id'] ?? ''),
            'footer_variant_id' => trim((string) ($row['footer_variant_id'] ?? '')) ?: null,
            'navigation_design_id' => trim((string) ($row['navigation_design_id'] ?? '')) ?: null,
            'created_at' => (string) ($row['created_at'] ?? ''),
            'updated_at' => (string) ($row['updated_at'] ?? ''),
            'updated_by_user_id' => (string) ($row['updated_by_user_id'] ?? ''),
        ];
    }
}
