<?php

declare(strict_types=1);

namespace ApiModel\Infrastructure\Persistence\Repositories;

use ApiModel\Domain\Repository\ChartAccountRepositoryInterface;
use ApiModel\Infrastructure\Persistence\Database;
use PDO;

final class PdoChartAccountRepository implements ChartAccountRepositoryInterface
{
    public function __construct(private readonly PDO $pdo) {}

    public function findById(string $id): ?array
    {
        $st = $this->pdo->prepare('SELECT * FROM chart_accounts WHERE id = ?');
        $st->execute([$id]);
        $row = $st->fetch();

        return $row !== false ? $row : null;
    }

    public function findByCode(string $companyId, string $code): ?array
    {
        $st = $this->pdo->prepare('SELECT * FROM chart_accounts WHERE company_id = ? AND code = ?');
        $st->execute([$companyId, $code]);
        $row = $st->fetch();

        return $row !== false ? $row : null;
    }

    public function listByCompany(string $companyId): array
    {
        $st = $this->pdo->prepare(
            'SELECT * FROM chart_accounts WHERE company_id = ? ORDER BY code ASC'
        );
        $st->execute([$companyId]);

        return $st->fetchAll();
    }

    public function insert(
        string $id,
        string $companyId,
        ?string $parentId,
        string $code,
        string $name,
        string $accountType,
        bool $isHeader
    ): void {
        $this->pdo->prepare(
            'INSERT INTO chart_accounts (id, company_id, parent_id, code, name, account_type, is_header, is_active)
             VALUES (?, ?, ?, ?, ?, ?, ?, TRUE)'
        )->execute([$id, $companyId, $parentId, $code, $name, $accountType, Database::bool($isHeader)]);
    }

    public function update(
        string $id,
        ?string $parentId,
        string $code,
        string $name,
        string $accountType,
        bool $isHeader,
        bool $isActive
    ): void {
        $this->pdo->prepare(
            'UPDATE chart_accounts
             SET parent_id = ?, code = ?, name = ?, account_type = ?, is_header = ?, is_active = ?, updated_at = CURRENT_TIMESTAMP
             WHERE id = ?'
        )->execute([$parentId, $code, $name, $accountType, Database::bool($isHeader), Database::bool($isActive), $id]);
    }

    public function hasChildren(string $id): bool
    {
        $st = $this->pdo->prepare('SELECT 1 FROM chart_accounts WHERE parent_id = ? LIMIT 1');
        $st->execute([$id]);

        return (bool) $st->fetchColumn();
    }
}
