<?php
/**
 * Design convention writes and compliance reporting.
 *
 * @package LolaCoreForBricks
 */

declare(strict_types=1);

namespace LolaCoreForBricks\Gateways;

use LolaCoreForBricks\Support\DesignConventionStore;
use LolaCoreForBricks\Support\ExternalFrameworkDetector;

/**
 * Persists the Bricks design convention for the site.
 */
class ConventionGateway
{
    /**
     * @param array<string, mixed> $params
     * @return array<string, mixed>
     */
    public function setDesignConvention(array $params): array
    {
        $payload = [
            'naming_pattern'     => $params['naming_pattern'] ?? '',
            'variable_policy'    => $params['variable_policy'] ?? '',
            'external_framework' => $params['external_framework'] ?? '',
            'protected_prefixes' => $params['protected_prefixes'] ?? [],
            'notes'              => $params['notes'] ?? '',
            'examples_valid'     => $params['examples_valid'] ?? [],
            'examples_invalid'   => $params['examples_invalid'] ?? [],
        ];

        $hasInput = trim((string) $payload['naming_pattern']) !== ''
            || trim((string) $payload['variable_policy']) !== ''
            || trim((string) $payload['external_framework']) !== '';

        if (!$hasInput && empty($payload['protected_prefixes']) && trim((string) $payload['notes']) === '') {
            return $this->failure(
                'Tell me the naming pattern, variable policy, or framework to save for this site.',
                'missing_convention'
            );
        }

        if (trim((string) $payload['naming_pattern']) === '' && trim((string) $payload['external_framework']) === '') {
            $detected = (new ExternalFrameworkDetector())->detect();
            if ($detected !== null) {
                $payload['external_framework'] = (string) $detected['framework'];
                if (trim((string) $payload['naming_pattern']) === '') {
                    $payload['naming_pattern'] = (string) $detected['suggested_pattern'];
                }
            }
        }

        $beforeStats = DesignConventionStore::classComplianceStats();
        $convention  = DesignConventionStore::save(array_filter(
            $payload,
            static fn (mixed $value): bool => $value !== null && $value !== ''
        ));
        $afterStats  = DesignConventionStore::classComplianceStats();

        return [
            'success'    => true,
            'message'    => 'Design convention saved for this site.',
            'convention' => $convention,
            'compliance' => [
                'before' => $beforeStats,
                'after'  => $afterStats,
            ],
        ];
    }

    /**
     * @return array{success: false, message: string, error: string}
     */
    private function failure(string $message, string $error): array
    {
        return [
            'success' => false,
            'message' => $message,
            'error'   => $error,
        ];
    }
}
