<?php

declare(strict_types=1);

namespace SeoScope\Repositories;

use PDO;

final class ProjectRepository
{
    public function __construct(
        private PDO $pdo,
        private string $tablePrefix,
        private int $userId = 1
    ) {
    }

    private function table(): string
    {
        return '`' . str_replace('`', '``', $this->tablePrefix . 'projects') . '`';
    }

    /**
     * @return list<array{id:int,name:string,site_url:string,notes:?string,gsc_property:?string,created_at:string,updated_at:string}>
     */
    public function all(): array
    {
        $t = $this->table();
        $stmt = $this->pdo->prepare(
            "SELECT id, name, site_url, notes, gsc_property, created_at, updated_at
             FROM {$t}
             WHERE user_id = ?
             ORDER BY name ASC"
        );
        $stmt->execute([$this->userId]);
        $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
        $out = [];
        foreach ($rows as $row) {
            $out[] = $this->mapRow($row);
        }
        return $out;
    }

    /**
     * @return array{id:int,name:string,site_url:string,notes:?string,gsc_property:?string,created_at:string,updated_at:string}|null
     */
    public function find(int $id): ?array
    {
        $t = $this->table();
        $stmt = $this->pdo->prepare(
            "SELECT id, name, site_url, notes, gsc_property, created_at, updated_at
             FROM {$t}
             WHERE user_id = ? AND id = ?
             LIMIT 1"
        );
        $stmt->execute([$this->userId, $id]);
        $row = $stmt->fetch(PDO::FETCH_ASSOC);
        return $row ? $this->mapRow($row) : null;
    }

    public function create(string $name, string $siteUrl, ?string $notes): int
    {
        $now = date('Y-m-d H:i:s');
        $t = $this->table();
        $stmt = $this->pdo->prepare(
            "INSERT INTO {$t} (user_id, name, site_url, notes, gsc_property, created_at, updated_at)
             VALUES (?, ?, ?, ?, ?, ?, ?)"
        );
        $stmt->execute([$this->userId, $name, $siteUrl, $notes, null, $now, $now]);
        return (int) $this->pdo->lastInsertId();
    }

    public function update(int $id, string $name, string $siteUrl, ?string $notes, ?string $gscProperty): void
    {
        $t = $this->table();
        $stmt = $this->pdo->prepare(
            "UPDATE {$t}
             SET name = ?, site_url = ?, notes = ?, gsc_property = ?, updated_at = ?
             WHERE user_id = ? AND id = ?"
        );
        $stmt->execute([$name, $siteUrl, $notes, $gscProperty, date('Y-m-d H:i:s'), $this->userId, $id]);
    }

    public function delete(int $id): void
    {
        $t = $this->table();
        $stmt = $this->pdo->prepare("DELETE FROM {$t} WHERE user_id = ? AND id = ? LIMIT 1");
        $stmt->execute([$this->userId, $id]);
    }

    /**
     * @param array<string, mixed> $row
     */
    private function mapRow(array $row): array
    {
        return [
            'id' => (int) $row['id'],
            'name' => (string) $row['name'],
            'site_url' => (string) $row['site_url'],
            'notes' => $row['notes'] !== null ? (string) $row['notes'] : null,
            'gsc_property' => $row['gsc_property'] !== null ? (string) $row['gsc_property'] : null,
            'created_at' => (string) $row['created_at'],
            'updated_at' => (string) $row['updated_at'],
        ];
    }
}
