<?php

namespace App\Modules\Citizenship\TR;

use App\Core\Citizenship\AbstractCitizenship;
use App\Core\Citizenship\Api\CitizenshipApiProviderManager;
use App\Modules\Citizenship\TR\ApiProviders\Mock\Mock;
use App\Modules\Citizenship\TR\ApiProviders\Nvi\Nvi;

class TR extends AbstractCitizenship
{
    public function getVerificationFields(): array
    {
        return [
            'individual_id' => [
                'type' => 'text',
                'label' => 'TC Kimlik No',
                'placeholder' => '12345678901',
                'group' => 'individual',
            ],
            'birth_year' => [
                'type' => 'number',
                'label' => 'Doğum Yılı',
                'placeholder' => '1990',
                'group' => 'individual',
            ],
            'company_id' => [
                'type' => 'text',
                'label' => 'Vergi Kimlik No',
                'placeholder' => '1234567890',
                'group' => 'company',
            ],
            'tax_office' => [
                'type' => 'text',
                'label' => 'Vergi Dairesi',
                'placeholder' => 'Kadıköy',
                'group' => 'company',
            ],
        ];
    }

    public function validateField(string $fieldKey, string $value, array $allData = []): array
    {
        return match ($fieldKey) {
            'individual_id' => $this->validateTcKimlik($value, $allData),
            'company_id' => $this->validateVkn($value),
            'birth_year' => $this->validateBirthYear($value),
            'tax_office' => strlen(trim($value)) >= 2
                ? $this->successResult('Geçerli vergi dairesi.')
                : $this->failResult('Vergi dairesi en az 2 karakter olmalıdır.'),
            default => $this->successResult(),
        };
    }

    public function getConfigFields(): array
    {
        return [
            'gib_enabled' => ['type' => 'boolean', 'label' => 'GİB Vergi No Doğrulama', 'default' => false],
            'reject_even_tc' => ['type' => 'boolean', 'label' => 'Çift TC Kimlik No Reddet', 'default' => false, 'description' => 'Son hanesi çift olan TC Kimlik numaralarını reddeder.'],
            'api_provider' => [
                'type' => 'select',
                'label' => 'API Sağlayıcı',
                'options' => app()->environment(['local', 'testing'])
                    ? ['nvi' => 'NVI', 'mock' => 'Mock']
                    : ['nvi' => 'NVI'],
                'default' => 'nvi',
            ],
        ];
    }

    public function getApiProviders(): array
    {
        $manager = new CitizenshipApiProviderManager();
        $manager->register('nvi', Nvi::class);
        if (app()->environment(['local', 'testing'])) {
            $manager->register('mock', Mock::class);
        }

        return $manager->listAvailable();
    }

    protected function getModuleLabel(): string
    {
        return 'TR — Türkiye Kimlik Doğrulama';
    }

    protected function getModuleDescription(): string
    {
        return 'TC Kimlik No checksum + VKN doğrulama, NVI/GİB API desteği';
    }

    // --- Internal validation methods ---

    private function validateTcKimlik(string $idNumber, array $allData = []): array
    {
        $idNumber = trim($idNumber);

        if (! preg_match('/^\d{11}$/', $idNumber)) {
            return $this->failResult('TC Kimlik No 11 haneli olmalıdır.');
        }

        if ($idNumber[0] === '0') {
            return $this->failResult('TC Kimlik No sıfır ile başlayamaz.');
        }

        // Checksum validation
        $digits = array_map('intval', str_split($idNumber));
        $oddSum = $digits[0] + $digits[2] + $digits[4] + $digits[6] + $digits[8];
        $evenSum = $digits[1] + $digits[3] + $digits[5] + $digits[7];
        $check10 = ($oddSum * 7 - $evenSum) % 10;
        if ($check10 < 0) {
            $check10 += 10;
        }

        if ($check10 !== $digits[9]) {
            return $this->failResult('Geçersiz TC Kimlik No.');
        }

        $sumFirst10 = array_sum(array_slice($digits, 0, 10));
        if ($sumFirst10 % 10 !== $digits[10]) {
            return $this->failResult('Geçersiz TC Kimlik No.');
        }

        // Reject even TC numbers if config enabled
        if ($this->getConfig('reject_even_tc', false)) {
            $lastDigit = $digits[10];
            if ($lastDigit % 2 === 0) {
                return $this->failResult('Çift haneli TC Kimlik No kabul edilmiyor.');
            }
        }

        // API verification if enabled (gate read from citizenship_country_settings.api_verification_enabled)
        if ($this->isApiVerificationEnabled()) {
            return $this->verifyViaApi(array_merge($allData, ['individual_id' => $idNumber]));
        }

        return $this->successResult('Geçerli TC Kimlik No.');
    }

    /**
     * Check whether API verification is enabled for the TR country setting.
     * Reads `api_verification_enabled` directly from citizenship_country_settings,
     * because CitizenshipManager only exposes Setting-table keys via getConfig().
     */
    protected function isApiVerificationEnabled(): bool
    {
        $setting = \App\Models\CitizenshipCountrySetting::where('country_code', 'TR')->first();

        return (bool) ($setting?->api_verification_enabled ?? false);
    }

    private function getApiProvider(): string
    {
        $setting = \App\Models\CitizenshipCountrySetting::where('country_code', 'TR')->first();

        return (string) ($setting?->api_provider ?? 'nvi');
    }

    private function getApiProviderConfig(): array
    {
        $setting = \App\Models\CitizenshipCountrySetting::where('country_code', 'TR')->first();
        $cfg = $setting?->api_provider_config ?? [];
        if (! is_array($cfg)) {
            $cfg = json_decode((string) $cfg, true) ?: [];
        }

        return $cfg;
    }

    protected function verifyViaApi(array $data): array
    {
        $manager = new CitizenshipApiProviderManager();
        $manager->register('nvi', Nvi::class);
        if (app()->environment(['local', 'testing'])) {
            $manager->register('mock', Mock::class);
        }

        $providerCode = $this->getApiProvider();
        $providerConfig = $this->getApiProviderConfig();

        $provider = $manager->get($providerCode, $providerConfig);
        if (! $provider) {
            return $this->failResult("Bilinmeyen API sağlayıcı: {$providerCode}");
        }

        $result = $provider->verify($data);

        return $result['valid']
            ? $this->successResult($result['message'] ?? 'TC Kimlik No doğrulandı.')
            : $this->failResult($result['message'] ?? 'TC Kimlik No doğrulanamadı.');
    }

    private function validateVkn(string $vkn): array
    {
        $vkn = trim($vkn);

        if (! preg_match('/^\d{10}$/', $vkn)) {
            return $this->failResult('Vergi No 10 haneli olmalıdır.');
        }

        // VKN checksum
        $digits = array_map('intval', str_split($vkn));
        $sum = 0;

        for ($i = 0; $i < 9; $i++) {
            $tmp = ($digits[$i] + (9 - $i)) % 10;
            $sum += ($tmp * pow(2, (9 - $i))) % 9;
            if ($tmp === 0 && (9 - $i) > 0) {
                $sum += 9;
            }
        }

        $checkDigit = (10 - ($sum % 10)) % 10;

        if ($checkDigit !== $digits[9]) {
            return $this->failResult('Geçersiz Vergi No.');
        }

        return $this->successResult('Geçerli Vergi No.');
    }

    private function validateBirthYear(string $value): array
    {
        $year = (int) $value;
        if ($year < 1900 || $year > (int) date('Y')) {
            return $this->failResult('Geçersiz doğum yılı.');
        }

        return $this->successResult('Geçerli doğum yılı.');
    }

}
