<?php

declare(strict_types=1);

namespace ApiModel\Infrastructure\Persistence\Repositories;

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

final class PdoUserAccessRepository implements UserAccessRepositoryInterface
{
    public function __construct(private readonly PDO $pdo) {}

    public function userHasCompanyAccess(string $userId, string $companyId): bool
    {
        $st = $this->pdo->prepare(
            'SELECT 1 FROM user_access WHERE user_id = ? AND company_id = ? LIMIT 1'
        );
        $st->execute([$userId, $companyId]);

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

    public function branchBelongsToCompany(string $branchId, string $companyId): bool
    {
        $st = $this->pdo->prepare(
            'SELECT 1 FROM branches WHERE id = ? AND company_id = ? LIMIT 1'
        );
        $st->execute([$branchId, $companyId]);

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

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

        return $st->fetchAll();
    }

    public function replaceForUser(string $userId, array $rows): void
    {
        $this->pdo->beginTransaction();

        try {
            $this->pdo->prepare('DELETE FROM user_access WHERE user_id = ?')->execute([$userId]);

            $st = $this->pdo->prepare(
                'INSERT INTO user_access (id, user_id, company_id, branch_id, can_manage, is_default)
                 VALUES (?, ?, ?, ?, ?, ?)'
            );

            foreach ($rows as $row) {
                $branchId = $row['branch_id'] ?? null;
                if ($branchId === '') {
                    $branchId = null;
                }

                $st->execute([
                    Database::uuid(),
                    $userId,
                    $row['company_id'],
                    $branchId,
                    Database::bool(! empty($row['can_manage'])),
                    Database::bool(! empty($row['is_default'])),
                ]);
            }

            $this->pdo->commit();
        } catch (\Throwable $e) {
            $this->pdo->rollBack();
            throw $e;
        }
    }
}
