<?php

namespace App\Domain\Identity\Services;

use Carbon\Carbon;

class EgyptianNidDecoder
{
    // Governorate codes → Arabic name
    private const GOVERNORATES = [
        '01' => 'القاهرة',
        '02' => 'الإسكندرية',
        '03' => 'بور سعيد',
        '04' => 'السويس',
        '11' => 'دمياط',
        '12' => 'الدقهلية',
        '13' => 'الشرقية',
        '14' => 'القليوبية',
        '15' => 'كفر الشيخ',
        '16' => 'الغربية',
        '17' => 'المنوفية',
        '18' => 'البحيرة',
        '19' => 'الإسماعيلية',
        '21' => 'الجيزة',
        '22' => 'بني سويف',
        '23' => 'الفيوم',
        '24' => 'المنيا',
        '25' => 'أسيوط',
        '26' => 'سوهاج',
        '27' => 'قنا',
        '28' => 'أسوان',
        '29' => 'الأقصر',
        '31' => 'البحر الأحمر',
        '32' => 'الوادي الجديد',
        '33' => 'مطروح',
        '34' => 'شمال سيناء',
        '35' => 'جنوب سيناء',
        '88' => 'أجنبي مقيم',
    ];

    public function decode(string $nid): array
    {
        $nid = preg_replace('/\D/', '', $nid);

        if (strlen($nid) !== 14) {
            return ['valid' => false];
        }

        $century = $nid[0];
        if (!in_array($century, ['2', '3'])) {
            return ['valid' => false];
        }

        $year = ($century === '2' ? '19' : '20') . substr($nid, 1, 2);
        $month = substr($nid, 3, 2);
        $day = substr($nid, 5, 2);

        try {
            $birthDate = Carbon::createFromDate((int)$year, (int)$month, (int)$day);
            if ($birthDate->isFuture()) {
                return ['valid' => false];
            }
        } catch (\Throwable) {
            return ['valid' => false];
        }

        $govCode = substr($nid, 7, 2);
        $governorate = self::GOVERNORATES[$govCode] ?? null;

        // Last digit before check digit (position 12, 0-indexed) determines gender
        // Odd = male, even = female
        $genderDigit = (int) $nid[12];
        $gender = ($genderDigit % 2 !== 0) ? 'male' : 'female';

        return [
            'valid' => true,
            'birth_date' => $birthDate->toDateString(),
            'gender' => $gender,
            'governorate_ar' => $governorate,
            'governorate_code' => $govCode,
        ];
    }
}
