<?php
declare(strict_types=1);

namespace App\Modules\Settings;

use PDO;

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

    /**
     * @return array<int, array{orderpro_status_code:string,shoppro_status_code:string,shoppro_status_name:string}>
     */
    public function listByIntegration(int $integrationId): array
    {
        if ($integrationId <= 0) {
            return [];
        }

        $statement = $this->pdo->prepare(
            'SELECT orderpro_status_code, shoppro_status_code, shoppro_status_name
            FROM order_status_mappings
            WHERE integration_id = :integration_id
            ORDER BY orderpro_status_code ASC'
        );
        $statement->execute(['integration_id' => $integrationId]);
        $rows = $statement->fetchAll(PDO::FETCH_ASSOC);

        if (!is_array($rows)) {
            return [];
        }

        $result = [];
        foreach ($rows as $row) {
            if (!is_array($row)) {
                continue;
            }

            $orderproCode = strtolower(trim((string) ($row['orderpro_status_code'] ?? '')));
            if ($orderproCode === '') {
                continue;
            }

            $result[] = [
                'orderpro_status_code' => $orderproCode,
                'shoppro_status_code' => trim((string) ($row['shoppro_status_code'] ?? '')),
                'shoppro_status_name' => trim((string) ($row['shoppro_status_name'] ?? '')),
            ];
        }

        return $result;
    }

    /**
     * @return array<int, array{code:string,name:string}>
     */
    public function listExternalStatuses(int $integrationId): array
    {
        if ($integrationId <= 0) {
            return [];
        }

        $statement = $this->pdo->prepare(
            'SELECT DISTINCT shoppro_status_code, shoppro_status_name
            FROM order_status_mappings
            WHERE integration_id = :integration_id
              AND shoppro_status_code <> ""
            ORDER BY shoppro_status_code ASC'
        );
        $statement->execute(['integration_id' => $integrationId]);
        $rows = $statement->fetchAll(PDO::FETCH_ASSOC);

        if (!is_array($rows)) {
            return [];
        }

        $result = [];
        foreach ($rows as $row) {
            if (!is_array($row)) {
                continue;
            }

            $code = trim((string) ($row['shoppro_status_code'] ?? ''));
            if ($code === '') {
                continue;
            }

            $result[] = [
                'code' => $code,
                'name' => trim((string) ($row['shoppro_status_name'] ?? $code)),
            ];
        }

        return $result;
    }

    /**
     * @param array<int, array{orderpro_status_code:string,shoppro_status_code:string,shoppro_status_name:string}> $mappings
     */
    public function replaceForIntegration(int $integrationId, array $mappings): void
    {
        if ($integrationId <= 0) {
            return;
        }

        $deleteStatement = $this->pdo->prepare(
            'DELETE FROM order_status_mappings WHERE integration_id = :integration_id'
        );
        $deleteStatement->execute(['integration_id' => $integrationId]);

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

        $insertStatement = $this->pdo->prepare(
            'INSERT INTO order_status_mappings (
                integration_id, orderpro_status_code, shoppro_status_code, shoppro_status_name, created_at, updated_at
            ) VALUES (
                :integration_id, :orderpro_status_code, :shoppro_status_code, :shoppro_status_name, NOW(), NOW()
            )'
        );

        foreach ($mappings as $mapping) {
            $orderproCode = strtolower(trim((string) ($mapping['orderpro_status_code'] ?? '')));
            $shopproCode = trim((string) ($mapping['shoppro_status_code'] ?? ''));
            if ($orderproCode === '' || $shopproCode === '') {
                continue;
            }

            $shopproName = trim((string) ($mapping['shoppro_status_name'] ?? ''));
            $insertStatement->execute([
                'integration_id' => $integrationId,
                'orderpro_status_code' => $orderproCode,
                'shoppro_status_code' => $shopproCode,
                'shoppro_status_name' => $shopproName !== '' ? $shopproName : null,
            ]);
        }
    }
}
