<?php

declare(strict_types=1);

namespace ApiModel\Infrastructure\Persistence\Repositories;

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

final class PdoCompanyRepository implements CompanyRepositoryInterface
{
    public function __construct(private readonly PDO $pdo) {}

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

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

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

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

    public function listAll(): array
    {
        $st = $this->pdo->query('SELECT * FROM companies ORDER BY legal_name ASC');

        return $st->fetchAll();
    }

    public function listForUser(string $userId): array
    {
        $st = $this->pdo->prepare(
            'SELECT c.*
             FROM companies c
             INNER JOIN user_access ua ON ua.company_id = c.id
             WHERE ua.user_id = ?
             ORDER BY c.legal_name ASC'
        );
        $st->execute([$userId]);

        return $st->fetchAll();
    }

    public function insert(
        string $id,
        string $legalName,
        ?string $tradeName,
        string $taxId,
        string $baseCurrency,
        ?string $email,
        ?string $phone,
        ?string $address
    ): void {
        $this->pdo->prepare(
            'INSERT INTO companies (id, legal_name, trade_name, tax_id, base_currency, email, phone, address, is_active)
             VALUES (?, ?, ?, ?, ?, ?, ?, ?, TRUE)'
        )->execute([$id, $legalName, $tradeName, $taxId, $baseCurrency, $email, $phone, $address]);
    }

    public function update(
        string $id,
        string $legalName,
        ?string $tradeName,
        string $taxId,
        string $baseCurrency,
        ?string $email,
        ?string $phone,
        ?string $address,
        bool $isActive
    ): void {
        $this->pdo->prepare(
            'UPDATE companies
             SET legal_name = ?, trade_name = ?, tax_id = ?, base_currency = ?, email = ?, phone = ?, address = ?,
                 is_active = ?, updated_at = CURRENT_TIMESTAMP
             WHERE id = ?'
        )->execute([$legalName, $tradeName, $taxId, $baseCurrency, $email, $phone, $address, Database::bool($isActive), $id]);
    }
}
