<?php
declare(strict_types=1);

namespace App\Modules\Settings;

use PDO;

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

    /**
     * @return array<int, array<string, mixed>>
     */
    public function listMappings(): array
    {
        $stmt = $this->pdo->query('SELECT * FROM allegro_delivery_method_mappings ORDER BY order_delivery_method ASC');
        $rows = $stmt !== false ? $stmt->fetchAll(PDO::FETCH_ASSOC) : [];
        return is_array($rows) ? $rows : [];
    }

    /**
     * @return array<string, mixed>|null
     */
    public function findByOrderMethod(string $orderDeliveryMethod): ?array
    {
        $stmt = $this->pdo->prepare('SELECT * FROM allegro_delivery_method_mappings WHERE order_delivery_method = :method LIMIT 1');
        $stmt->execute(['method' => $orderDeliveryMethod]);
        $row = $stmt->fetch(PDO::FETCH_ASSOC);
        return is_array($row) ? $row : null;
    }

    /**
     * @param array<int, array{order_delivery_method: string, allegro_delivery_method_id: string, allegro_credentials_id: string, allegro_carrier_id: string, allegro_service_name: string}> $mappings
     */
    public function saveMappings(array $mappings): void
    {
        $this->pdo->exec('DELETE FROM allegro_delivery_method_mappings');

        if ($mappings === []) {
            return;
        }

        $stmt = $this->pdo->prepare(
            'INSERT INTO allegro_delivery_method_mappings
                (order_delivery_method, carrier, allegro_delivery_method_id, allegro_credentials_id, allegro_carrier_id, allegro_service_name)
             VALUES
                (:order_delivery_method, :carrier, :allegro_delivery_method_id, :allegro_credentials_id, :allegro_carrier_id, :allegro_service_name)'
        );

        foreach ($mappings as $mapping) {
            $orderMethod = trim((string) ($mapping['order_delivery_method'] ?? ''));
            $allegroMethodId = trim((string) ($mapping['allegro_delivery_method_id'] ?? ''));
            $carrier = trim((string) ($mapping['carrier'] ?? 'allegro'));
            if ($orderMethod === '' || $allegroMethodId === '') {
                continue;
            }

            $stmt->execute([
                'order_delivery_method' => $orderMethod,
                'carrier' => $carrier !== '' ? $carrier : 'allegro',
                'allegro_delivery_method_id' => $allegroMethodId,
                'allegro_credentials_id' => trim((string) ($mapping['allegro_credentials_id'] ?? '')),
                'allegro_carrier_id' => trim((string) ($mapping['allegro_carrier_id'] ?? '')),
                'allegro_service_name' => trim((string) ($mapping['allegro_service_name'] ?? '')),
            ]);
        }
    }

    /**
     * @return array<int, string>
     */
    public function getDistinctOrderDeliveryMethods(): array
    {
        $stmt = $this->pdo->query(
            "SELECT DISTINCT external_carrier_id FROM orders
             WHERE external_carrier_id IS NOT NULL
               AND external_carrier_id != ''
               AND source = 'allegro'
               AND external_carrier_id NOT REGEXP '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$'
             ORDER BY external_carrier_id ASC"
        );
        $rows = $stmt !== false ? $stmt->fetchAll(PDO::FETCH_COLUMN) : [];
        return is_array($rows) ? $rows : [];
    }
}
