<?php

namespace App\Http\Controllers;

use App\Models\Applicant;
use App\Models\Application;
use App\Models\JobListing;
use App\Models\JobStage;
use App\Models\StageResponse;
use App\Models\Setting;
use App\Models\Ad;
use App\Services\NotificationService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Mail;
use Illuminate\Validation\ValidationException;

class ApplicantController extends Controller
{
    /**
     * Show login/register form
     */
    public function showLogin(Request $request)
    {
        $jobId = $request->query('job_id');
        $registerStartedAt = now()->timestamp;
        $request->session()->put('register_started_at', $registerStartedAt);
        return view('auth.login', compact('jobId', 'registerStartedAt'));
    }

    /**
     * Handle registration
     */
    public function register(Request $request)
    {
        // Normalize user input first so validation is consistent.
        $request->merge([
            'whatsapp' => preg_replace('/[^0-9+]/', '', (string) $request->input('whatsapp', '')),
        ]);

        // Honeypot field should stay empty; bots often fill all fields.
        if ($request->filled('company_website')) {
            throw ValidationException::withMessages([
                'security' => 'Validasi keamanan gagal. Silakan muat ulang halaman lalu coba lagi.',
            ]);
        }

        $formStartedAt = (int) ($request->session()->get('register_started_at') ?: $request->input('register_started_at', 0));
        $formAge = now()->timestamp - $formStartedAt;
        if ($formStartedAt <= 0 || $formAge < 3 || $formAge > 7200) {
            throw ValidationException::withMessages([
                'security' => 'Validasi keamanan gagal. Silakan muat ulang halaman lalu coba lagi.',
            ]);
        }

        // Verify CAPTCHA token before creating account.
        $this->verifyRecaptcha($request);

        $request->validate([
            'name' => 'required|string|max:255',
            'email' => 'required|email|max:255|unique:applicants,email',
            'whatsapp' => ['required', 'string', 'max:20', 'regex:/^(\+62|62|0)8[1-9][0-9]{6,12}$/'],
            'education' => 'required|string',
            'gender' => 'required|in:Laki-laki,Perempuan',
            'birth_date' => 'required|date|before:today',
            'job_id' => 'nullable|exists:job_listings,id',
            'register_started_at' => 'nullable|integer',
        ], [
            'email.unique' => 'Email sudah terdaftar. Silakan login dengan password Anda.',
            'whatsapp.regex' => 'Nomor WhatsApp harus format Indonesia (contoh: 0812xxxx atau +62812xxxx).',
        ]);

        $password = \Illuminate\Support\Str::random(10);
        $applicant = Applicant::create([
            'name' => $request->name,
            'email' => $request->email,
            'whatsapp' => $this->normalizeIndonesianWhatsapp($request->whatsapp),
            'education' => $request->education,
            'gender' => $request->gender,
            'birth_date' => $request->birth_date,
            'password' => $password,
        ]);
        session(['generated_password' => $password]);

        // Send password to applicant via email & WhatsApp
        $this->sendGeneratedPassword($applicant, $password);

        session(['applicant_id' => $applicant->id]);
        $request->session()->forget('register_started_at');
        $request->session()->regenerate(); // Session fixation protection

        if ($request->job_id) {
            return redirect()->route('ads.countdown', ['job' => $request->job_id]);
        }

        return redirect()->route('dashboard');
    }

    /**
     * Handle login
     */
    public function login(Request $request)
    {
        $request->validate([
            'email' => 'required|email',
            'password' => 'required',
        ]);

        $applicant = Applicant::where('email', $request->email)->first();

        if ($applicant && Hash::check($request->password, $applicant->password)) {
            session(['applicant_id' => $applicant->id]);
            $request->session()->regenerate(); // Session fixation protection, preserves all data including admin Auth

            if ($request->job_id) {
                return redirect()->route('ads.countdown', ['job' => $request->job_id]);
            }
            return redirect()->route('dashboard');
        }

        return back()->withErrors(['email' => 'Email atau password salah.'])->withInput();
    }

    /**
     * Submit job application (with optional CV)
     */
    public function submitApplication(Request $request, JobListing $job)
    {
        $applicantId = session('applicant_id');
        if (!$applicantId) return redirect()->route('login');

        // Check if job is still active and not past deadline
        if (!$job->is_active) {
            return redirect()->route('home')->with('error', 'Lowongan ini sudah tidak aktif.');
        }
        if ($job->deadline && $job->deadline->isPast()) {
            return redirect()->route('home')->with('error', 'Lowongan ini sudah melewati batas waktu pendaftaran.');
        }

        // Check if already applied
        $existing = Application::where('applicant_id', $applicantId)
            ->where('job_listing_id', $job->id)
            ->first();

        if ($existing) {
            return redirect()->route('dashboard')
                ->with('info', 'Anda sudah melamar untuk posisi ini.');
        }

        // Limit: max 3 applications per rolling 24 hours
        $dailyApplicationLimit = 3;
        $windowStart = now()->subDay();

        $applicationsInLast24Hours = Application::where('applicant_id', $applicantId)
            ->where(function ($query) use ($windowStart) {
                $query->where('applied_at', '>=', $windowStart)
                    ->orWhere(function ($q) use ($windowStart) {
                        // Fallback for legacy records that might not have applied_at
                        $q->whereNull('applied_at')
                            ->where('created_at', '>=', $windowStart);
                    });
            })
            ->count();

        if ($applicationsInLast24Hours >= $dailyApplicationLimit) {
            $limitMessage = 'Kami informasikan bahwa setiap akun hanya dapat melamar maksimal 3 pekerjaan dalam 1 hari. Silakan mencoba kembali untuk melamar pekerjaan lainnya pada hari berikutnya.';

            return redirect()->route('home')
                ->with('error', $limitMessage)
                ->with('application_limit_popup', $limitMessage);
        }

        // Handle document uploads (optional, multiple)
        $request->validate([
            'documents' => 'nullable|array',
            'documents.*' => 'file|mimes:pdf,doc,docx,jpg,jpeg,png|max:5120',
        ]);

        $documentPaths = [];
        if ($request->hasFile('documents')) {
            foreach ($request->file('documents') as $file) {
                $documentPaths[] = $file->store('documents', 'public');
            }
        }

        $application = Application::create([
            'applicant_id' => $applicantId,
            'job_listing_id' => $job->id,
            'cv_path' => json_encode($documentPaths),
            'status' => 'applied',
            'current_stage' => 0,
            'applied_at' => now(),
        ]);

        // Auto-send notification: application received (immediate)
        $notificationService = app(NotificationService::class);
        $notificationService->notifyStatusChange($application, 'applied');

        // Schedule the next stage notification (H+interval days)
        $notificationService->scheduleNextStageNotification($application);

        return redirect()->route('dashboard')
            ->with('success', 'Lamaran berhasil dikirim! Silakan cek email dan WhatsApp Anda.');
    }

    /**
     * Dashboard
     */
    public function dashboard()
    {
        $applicantId = session('applicant_id');
        $applicant = Applicant::findOrFail($applicantId);
        $applications = Application::where('applicant_id', $applicantId)
            ->with(['jobListing.stages', 'stageResponses'])
            ->latest()
            ->get();

        $bannerTop = Ad::getByPosition('banner_top');
        $inArticleAd = Ad::getByPosition('in_article');
        $nativeAd = Ad::getByPosition('native');
        $mobileBanner = Ad::getByPosition('mobile_banner');

        // Retrieve and immediately clear generated password from session
        $generatedPassword = session()->pull('generated_password');

        return view('dashboard', compact('applicant', 'applications', 'bannerTop', 'inArticleAd', 'nativeAd', 'mobileBanner', 'generatedPassword'));
    }

    /**
     * Show dynamic stage form
     */
    public function showStageForm(Application $application, JobStage $stage)
    {
        $applicantId = session('applicant_id');
        if ($application->applicant_id !== $applicantId) abort(403);

        // Eager load to avoid N+1 queries in view
        $application->load('jobListing.stages');

        // Verify stage belongs to the same job as this application
        if ($stage->job_listing_id !== $application->job_listing_id) abort(404);

        // Check that the current status allows filling this stage's form
        $expectedStatus = 'stage' . $stage->stage_number . '_passed';
        if ($application->status !== $expectedStatus) {
            return redirect()->route('dashboard')->with('error', 'Anda belum bisa mengisi formulir ini.');
        }

        // Check if already filled
        if ($application->hasFilledStage($stage->id)) {
            return redirect()->route('dashboard')->with('info', 'Formulir ini sudah terisi.');
        }

        $countdownAd = Ad::getByPosition('countdown');
        $formBanner = Ad::getByPosition('banner_bottom');
        $nativeAd = Ad::getByPosition('native');
        $mobileBanner = Ad::getByPosition('mobile_banner');

        return view('forms.stage-form', compact('application', 'stage', 'countdownAd', 'formBanner', 'nativeAd', 'mobileBanner'));
    }

    /**
     * Submit dynamic stage form
     */
    public function submitStageForm(Request $request, Application $application, JobStage $stage)
    {
        $applicantId = session('applicant_id');
        if ($application->applicant_id !== $applicantId) abort(403);

        // Verify stage belongs to the same job as this application
        if ($stage->job_listing_id !== $application->job_listing_id) abort(404);

        $expectedStatus = 'stage' . $stage->stage_number . '_passed';
        if ($application->status !== $expectedStatus) {
            return redirect()->route('dashboard')->with('error', 'Anda belum bisa mengisi formulir ini.');
        }

        // Validate required fields
        $formFields = $stage->form_fields ?? [];
        $rules = [];
        foreach ($formFields as $field) {
            $fieldName = 'field_' . ($field['name'] ?? '');
            $fieldType = $field['type'] ?? 'text';
            if ($fieldType === 'file') {
                if (!empty($field['required'])) {
                    $rules[$fieldName] = 'required|file|mimes:pdf,doc,docx,jpg,jpeg,png|max:5120';
                } else {
                    $rules[$fieldName] = 'nullable|file|mimes:pdf,doc,docx,jpg,jpeg,png|max:5120';
                }
            } elseif (!empty($field['required'])) {
                $rules[$fieldName] = 'required';
            }
        }
        $request->validate($rules);

        // Collect responses
        $responses = [];
        foreach ($formFields as $field) {
            $fieldName = 'field_' . ($field['name'] ?? '');
            $fieldType = $field['type'] ?? 'text';

            if ($fieldType === 'file') {
                // Handle file upload
                if ($request->hasFile($fieldName)) {
                    $filePath = $request->file($fieldName)->store('stage_documents', 'public');
                    $value = $filePath;
                } else {
                    $value = null;
                }
            } else {
                $value = $request->input($fieldName);
            }

            $responses[$field['name'] ?? $fieldName] = [
                'label' => $field['label'] ?? $field['name'] ?? '',
                'type' => $fieldType,
                'value' => is_array($value) ? implode(', ', $value) : $value,
            ];
        }

        StageResponse::create([
            'application_id' => $application->id,
            'job_stage_id' => $stage->id,
            'responses' => $responses,
            'cv_path' => null,
            'submitted_at' => now(),
        ]);

        // Update application status
        $newStatus = 'stage' . $stage->stage_number . '_form_filled';
        $application->update([
            'status' => $newStatus,
            'current_stage' => $stage->stage_number,
        ]);

        // Auto-send notification: form submitted
        $notificationService = app(NotificationService::class);
        $notificationService->notifyStatusChange($application, $newStatus);

        // Schedule the next stage notification (H+interval days from form submission)
        $notificationService->scheduleNextStageNotification($application);

        return redirect()->route('dashboard')
            ->with('success', "Formulir \"{$stage->name}\" berhasil dikirim!");
    }

    /**
     * Send generated password to applicant via Email & WhatsApp
     */
    private function sendGeneratedPassword(Applicant $applicant, string $password): void
    {
        $siteName = Setting::get('site_name', config('app.name', 'Bursa Kerja'));
        $siteUrl = config('app.url');
        $safeName = e($applicant->name);

        // Send via Email
        try {
            $html = <<<HTML
            <!DOCTYPE html>
            <html>
            <head><meta charset="utf-8"></head>
            <body style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto; padding: 20px; background: #f5f5f5;">
                <div style="background: white; border-radius: 10px; padding: 30px; box-shadow: 0 2px 10px rgba(0,0,0,0.1);">
                    <div style="text-align: center; margin-bottom: 20px;">
                        <h2 style="color: #4F46E5; margin: 0;">{$siteName}</h2>
                    </div>
                    <hr style="border: none; border-top: 2px solid #E5E7EB; margin: 20px 0;">
                    <p>Halo <strong>{$safeName}</strong>,</p>
                    <p>Akun Anda telah berhasil dibuat. Berikut adalah data login Anda:</p>
                    <div style="background: #F3F4F6; border-radius: 8px; padding: 15px; margin: 15px 0;">
                        <p style="margin: 5px 0;"><strong>Email:</strong> {$applicant->email}</p>
                        <p style="margin: 5px 0;"><strong>Password:</strong> <code style="background: #E5E7EB; padding: 2px 6px; border-radius: 4px;">{$password}</code></p>
                    </div>
                    <p style="color: #EF4444; font-size: 13px;">⚠️ Segera ubah password Anda setelah login demi keamanan akun.</p>
                    <p>Login di: <a href="{$siteUrl}/login">{$siteUrl}/login</a></p>
                    <hr style="border: none; border-top: 1px solid #E5E7EB; margin: 20px 0;">
                    <p style="color: #6B7280; font-size: 12px; text-align: center;">
                        Email ini dikirim secara otomatis oleh {$siteName}. Mohon tidak membalas email ini.
                    </p>
                </div>
            </body>
            </html>
            HTML;

            Mail::html($html, function ($mail) use ($applicant, $siteName) {
                $mail->to($applicant->email, $applicant->name)
                    ->subject("Akun Anda Telah Dibuat - {$siteName}");
            });
        } catch (\Exception $e) {
            Log::error('Failed to send registration password email: ' . $e->getMessage());
        }

        // Send via WhatsApp (Fonnte)
        $fonnteKey = Setting::get('fonnte_api_key', config('services.fonnte.key'));
        if ($fonnteKey && $applicant->whatsapp) {
            $waMessage = "Halo *{$applicant->name}*,\n\n"
                . "Akun Anda di *{$siteName}* telah berhasil dibuat.\n\n"
                . "📧 Email: {$applicant->email}\n"
                . "🔑 Password: {$password}\n\n"
                . "⚠️ Segera ubah password Anda setelah login.\n"
                . "Login di: {$siteUrl}/login";

            try {
                Http::withHeaders([
                    'Authorization' => $fonnteKey,
                ])->post('https://api.fonnte.com/send', [
                    'target' => $applicant->whatsapp,
                    'message' => $waMessage,
                    'countryCode' => '62',
                ]);
            } catch (\Exception $e) {
                Log::error('Failed to send registration password WhatsApp: ' . $e->getMessage());
            }
        }
    }

    /**
     * Logout
     */
    public function logout(Request $request)
    {
        session()->forget('applicant_id');
        session()->forget('generated_password');
        $request->session()->regenerateToken(); // Regenerate CSRF only, preserve admin session
        return redirect()->route('home')->with('success', 'Berhasil logout.');
    }

    /**
     * Convert Indonesian WA numbers into +62 format for consistent storage.
     */
    private function normalizeIndonesianWhatsapp(string $value): string
    {
        $digits = preg_replace('/[^0-9]/', '', $value);

        if (str_starts_with($digits, '0')) {
            $digits = '62' . substr($digits, 1);
        } elseif (!str_starts_with($digits, '62')) {
            $digits = '62' . $digits;
        }

        return '+' . $digits;
    }

    /**
     * Verify Google reCAPTCHA token from register form.
     */
    private function verifyRecaptcha(Request $request): void
    {
        $secretKey = (string) config('services.recaptcha.secret_key');
        $recaptchaType = (string) config('services.recaptcha.type', 'v3');
        $minScore = (float) config('services.recaptcha.min_score', 0.5);

        // If key is not configured, skip verification to avoid breaking local/dev.
        if ($secretKey === '') {
            return;
        }

        $token = (string) ($request->input('recaptcha_token') ?: $request->input('g-recaptcha-response', ''));
        if ($token === '') {
            throw ValidationException::withMessages([
                'recaptcha' => 'Validasi CAPTCHA tidak ditemukan. Silakan coba lagi.',
            ]);
        }

        try {
            $response = Http::asForm()
                ->timeout(10)
                ->post('https://www.google.com/recaptcha/api/siteverify', [
                    'secret' => $secretKey,
                    'response' => $token,
                    'remoteip' => $request->ip(),
                ]);

            $payload = (array) $response->json();

            if (!$response->ok() || !($payload['success'] ?? false)) {
                Log::warning('reCAPTCHA validation failed on applicant register', [
                    'ip' => $request->ip(),
                    'error_codes' => $payload['error-codes'] ?? [],
                    'type' => $recaptchaType,
                ]);

                throw ValidationException::withMessages([
                    'recaptcha' => 'Verifikasi CAPTCHA gagal. Silakan coba lagi.',
                ]);
            }

            if ($recaptchaType === 'v3') {
                $action = (string) ($payload['action'] ?? '');
                $score = (float) ($payload['score'] ?? 0);

                if ($action !== 'register' || $score < $minScore) {
                    Log::warning('reCAPTCHA v3 score/action rejected on applicant register', [
                        'ip' => $request->ip(),
                        'score' => $score,
                        'action' => $action,
                        'min_score' => $minScore,
                    ]);

                    throw ValidationException::withMessages([
                        'recaptcha' => 'Aktivitas terdeteksi tidak valid. Silakan coba lagi.',
                    ]);
                }
            }
        } catch (ValidationException $e) {
            throw $e;
        } catch (\Throwable $e) {
            Log::warning('Failed to reach reCAPTCHA verification endpoint', [
                'error' => $e->getMessage(),
            ]);

            throw ValidationException::withMessages([
                'recaptcha' => 'Layanan CAPTCHA sedang bermasalah. Coba beberapa saat lagi.',
            ]);
        }
    }

    /**
     * Show edit profile form
     */
    public function editProfile()
    {
        $applicantId = session('applicant_id');
        $applicant = Applicant::findOrFail($applicantId);
        $provinces = self::getProvinces();

        return view('profile.edit', compact('applicant', 'provinces'));
    }

    /**
     * Update profile
     */
    public function updateProfile(Request $request)
    {
        $applicantId = session('applicant_id');
        $applicant = Applicant::findOrFail($applicantId);

        $request->validate([
            'name' => 'required|string|max:255',
            'whatsapp' => 'required|string|max:20',
            'education' => 'required|string',
            'birth_date' => 'required|date|before:today',
            'gender' => 'required|in:Laki-laki,Perempuan',
            'province' => 'nullable|string|max:255',
            'city' => 'nullable|string|max:255',
        ]);

        $applicant->update($request->only([
            'name', 'whatsapp', 'education', 'birth_date', 'gender', 'province', 'city',
        ]));

        return redirect()->route('profile.edit')->with('success', 'Profil berhasil diperbarui!');
    }

    /**
     * Get cities by province (API for AJAX)
     */
    public function getCities($province)
    {
        $cities = self::getCitiesByProvince($province);
        return response()->json($cities);
    }

    /**
     * List of Indonesian provinces
     */
    public static function getProvinces(): array
    {
        return [
            'Aceh', 'Sumatera Utara', 'Sumatera Barat', 'Riau', 'Jambi',
            'Sumatera Selatan', 'Bengkulu', 'Lampung', 'Kepulauan Bangka Belitung',
            'Kepulauan Riau', 'DKI Jakarta', 'Jawa Barat', 'Jawa Tengah',
            'DI Yogyakarta', 'Jawa Timur', 'Banten', 'Bali',
            'Nusa Tenggara Barat', 'Nusa Tenggara Timur', 'Kalimantan Barat',
            'Kalimantan Tengah', 'Kalimantan Selatan', 'Kalimantan Timur',
            'Kalimantan Utara', 'Sulawesi Utara', 'Sulawesi Tengah',
            'Sulawesi Selatan', 'Sulawesi Tenggara', 'Gorontalo',
            'Sulawesi Barat', 'Maluku', 'Maluku Utara', 'Papua',
            'Papua Barat', 'Papua Selatan', 'Papua Tengah', 'Papua Pegunungan', 'Papua Barat Daya',
        ];
    }

    /**
     * Get cities/kabupaten by province
     */
    public static function getCitiesByProvince(string $province): array
    {
        $data = [
            'Aceh' => ['Kota Banda Aceh', 'Kota Sabang', 'Kota Langsa', 'Kota Lhokseumawe', 'Kota Subulussalam', 'Kab. Aceh Besar', 'Kab. Aceh Barat', 'Kab. Aceh Selatan', 'Kab. Aceh Tengah', 'Kab. Aceh Tenggara', 'Kab. Aceh Timur', 'Kab. Aceh Utara', 'Kab. Pidie', 'Kab. Bireuen', 'Kab. Simeulue', 'Kab. Aceh Singkil', 'Kab. Aceh Tamiang', 'Kab. Nagan Raya', 'Kab. Aceh Jaya', 'Kab. Aceh Barat Daya', 'Kab. Gayo Lues', 'Kab. Pidie Jaya', 'Kab. Bener Meriah'],
            'Sumatera Utara' => ['Kota Medan', 'Kota Binjai', 'Kota Pematang Siantar', 'Kota Tebing Tinggi', 'Kota Tanjung Balai', 'Kota Sibolga', 'Kota Padang Sidempuan', 'Kota Gunungsitoli', 'Kab. Deli Serdang', 'Kab. Langkat', 'Kab. Karo', 'Kab. Simalungun', 'Kab. Asahan', 'Kab. Labuhanbatu', 'Kab. Tapanuli Utara', 'Kab. Tapanuli Tengah', 'Kab. Tapanuli Selatan', 'Kab. Nias', 'Kab. Dairi', 'Kab. Toba Samosir', 'Kab. Mandailing Natal', 'Kab. Nias Selatan', 'Kab. Samosir', 'Kab. Serdang Bedagai', 'Kab. Humbang Hasundutan', 'Kab. Pakpak Bharat', 'Kab. Batu Bara', 'Kab. Padang Lawas', 'Kab. Padang Lawas Utara', 'Kab. Labuhanbatu Selatan', 'Kab. Labuhanbatu Utara', 'Kab. Nias Utara', 'Kab. Nias Barat'],
            'Sumatera Barat' => ['Kota Padang', 'Kota Bukittinggi', 'Kota Payakumbuh', 'Kota Solok', 'Kota Sawahlunto', 'Kota Padang Panjang', 'Kota Pariaman', 'Kab. Pesisir Selatan', 'Kab. Solok', 'Kab. Sijunjung', 'Kab. Tanah Datar', 'Kab. Agam', 'Kab. Lima Puluh Kota', 'Kab. Pasaman', 'Kab. Dharmasraya', 'Kab. Solok Selatan', 'Kab. Pasaman Barat', 'Kab. Kepulauan Mentawai'],
            'Riau' => ['Kota Pekanbaru', 'Kota Dumai', 'Kab. Kampar', 'Kab. Bengkalis', 'Kab. Indragiri Hulu', 'Kab. Indragiri Hilir', 'Kab. Pelalawan', 'Kab. Siak', 'Kab. Rokan Hulu', 'Kab. Rokan Hilir', 'Kab. Kuantan Singingi', 'Kab. Kepulauan Meranti'],
            'Jambi' => ['Kota Jambi', 'Kota Sungai Penuh', 'Kab. Batang Hari', 'Kab. Bungo', 'Kab. Kerinci', 'Kab. Merangin', 'Kab. Muaro Jambi', 'Kab. Sarolangun', 'Kab. Tanjung Jabung Barat', 'Kab. Tanjung Jabung Timur', 'Kab. Tebo'],
            'Sumatera Selatan' => ['Kota Palembang', 'Kota Prabumulih', 'Kota Pagar Alam', 'Kota Lubuklinggau', 'Kab. Ogan Komering Ulu', 'Kab. Ogan Komering Ilir', 'Kab. Muara Enim', 'Kab. Lahat', 'Kab. Musi Rawas', 'Kab. Musi Banyuasin', 'Kab. Banyuasin', 'Kab. Ogan Ilir', 'Kab. OKU Timur', 'Kab. OKU Selatan', 'Kab. Empat Lawang', 'Kab. Penukal Abab Lematang Ilir', 'Kab. Musi Rawas Utara'],
            'Bengkulu' => ['Kota Bengkulu', 'Kab. Bengkulu Selatan', 'Kab. Bengkulu Utara', 'Kab. Rejang Lebong', 'Kab. Kaur', 'Kab. Seluma', 'Kab. Mukomuko', 'Kab. Lebong', 'Kab. Kepahiang', 'Kab. Bengkulu Tengah'],
            'Lampung' => ['Kota Bandar Lampung', 'Kota Metro', 'Kab. Lampung Selatan', 'Kab. Lampung Tengah', 'Kab. Lampung Utara', 'Kab. Lampung Barat', 'Kab. Lampung Timur', 'Kab. Tanggamus', 'Kab. Tulang Bawang', 'Kab. Way Kanan', 'Kab. Pesawaran', 'Kab. Pringsewu', 'Kab. Mesuji', 'Kab. Tulang Bawang Barat', 'Kab. Pesisir Barat'],
            'Kepulauan Bangka Belitung' => ['Kota Pangkal Pinang', 'Kab. Bangka', 'Kab. Belitung', 'Kab. Bangka Barat', 'Kab. Bangka Tengah', 'Kab. Bangka Selatan', 'Kab. Belitung Timur'],
            'Kepulauan Riau' => ['Kota Batam', 'Kota Tanjung Pinang', 'Kab. Bintan', 'Kab. Karimun', 'Kab. Natuna', 'Kab. Lingga', 'Kab. Kepulauan Anambas'],
            'DKI Jakarta' => ['Jakarta Pusat', 'Jakarta Utara', 'Jakarta Barat', 'Jakarta Selatan', 'Jakarta Timur', 'Kepulauan Seribu'],
            'Jawa Barat' => ['Kota Bandung', 'Kota Bogor', 'Kota Bekasi', 'Kota Depok', 'Kota Cirebon', 'Kota Sukabumi', 'Kota Cimahi', 'Kota Tasikmalaya', 'Kota Banjar', 'Kab. Bandung', 'Kab. Bogor', 'Kab. Bekasi', 'Kab. Karawang', 'Kab. Subang', 'Kab. Purwakarta', 'Kab. Cianjur', 'Kab. Sukabumi', 'Kab. Garut', 'Kab. Tasikmalaya', 'Kab. Ciamis', 'Kab. Kuningan', 'Kab. Cirebon', 'Kab. Majalengka', 'Kab. Sumedang', 'Kab. Indramayu', 'Kab. Bandung Barat', 'Kab. Pangandaran'],
            'Jawa Tengah' => ['Kota Semarang', 'Kota Surakarta', 'Kota Salatiga', 'Kota Pekalongan', 'Kota Tegal', 'Kota Magelang', 'Kab. Semarang', 'Kab. Kendal', 'Kab. Demak', 'Kab. Grobogan', 'Kab. Pekalongan', 'Kab. Batang', 'Kab. Tegal', 'Kab. Brebes', 'Kab. Pemalang', 'Kab. Purbalingga', 'Kab. Banjarnegara', 'Kab. Banyumas', 'Kab. Cilacap', 'Kab. Kebumen', 'Kab. Purworejo', 'Kab. Magelang', 'Kab. Temanggung', 'Kab. Wonosobo', 'Kab. Boyolali', 'Kab. Klaten', 'Kab. Sukoharjo', 'Kab. Wonogiri', 'Kab. Karanganyar', 'Kab. Sragen', 'Kab. Blora', 'Kab. Rembang', 'Kab. Pati', 'Kab. Kudus', 'Kab. Jepara'],
            'DI Yogyakarta' => ['Kota Yogyakarta', 'Kab. Sleman', 'Kab. Bantul', 'Kab. Kulon Progo', 'Kab. Gunungkidul'],
            'Jawa Timur' => ['Kota Surabaya', 'Kota Malang', 'Kota Kediri', 'Kota Blitar', 'Kota Madiun', 'Kota Mojokerto', 'Kota Pasuruan', 'Kota Probolinggo', 'Kota Batu', 'Kab. Sidoarjo', 'Kab. Gresik', 'Kab. Lamongan', 'Kab. Tuban', 'Kab. Bojonegoro', 'Kab. Jombang', 'Kab. Mojokerto', 'Kab. Malang', 'Kab. Pasuruan', 'Kab. Probolinggo', 'Kab. Lumajang', 'Kab. Jember', 'Kab. Banyuwangi', 'Kab. Bondowoso', 'Kab. Situbondo', 'Kab. Kediri', 'Kab. Blitar', 'Kab. Tulungagung', 'Kab. Trenggalek', 'Kab. Nganjuk', 'Kab. Madiun', 'Kab. Magetan', 'Kab. Ngawi', 'Kab. Ponorogo', 'Kab. Pacitan', 'Kab. Bangkalan', 'Kab. Sampang', 'Kab. Pamekasan', 'Kab. Sumenep'],
            'Banten' => ['Kota Serang', 'Kota Tangerang', 'Kota Tangerang Selatan', 'Kota Cilegon', 'Kab. Serang', 'Kab. Tangerang', 'Kab. Pandeglang', 'Kab. Lebak'],
            'Bali' => ['Kota Denpasar', 'Kab. Badung', 'Kab. Gianyar', 'Kab. Tabanan', 'Kab. Klungkung', 'Kab. Bangli', 'Kab. Karangasem', 'Kab. Buleleng', 'Kab. Jembrana'],
            'Nusa Tenggara Barat' => ['Kota Mataram', 'Kota Bima', 'Kab. Lombok Barat', 'Kab. Lombok Tengah', 'Kab. Lombok Timur', 'Kab. Lombok Utara', 'Kab. Sumbawa', 'Kab. Sumbawa Barat', 'Kab. Dompu', 'Kab. Bima'],
            'Nusa Tenggara Timur' => ['Kota Kupang', 'Kab. Kupang', 'Kab. Timor Tengah Selatan', 'Kab. Timor Tengah Utara', 'Kab. Belu', 'Kab. Alor', 'Kab. Flores Timur', 'Kab. Sikka', 'Kab. Ende', 'Kab. Nagekeo', 'Kab. Ngada', 'Kab. Manggarai', 'Kab. Manggarai Barat', 'Kab. Manggarai Timur', 'Kab. Sumba Barat', 'Kab. Sumba Timur', 'Kab. Sumba Tengah', 'Kab. Sumba Barat Daya', 'Kab. Lembata', 'Kab. Rote Ndao', 'Kab. Sabu Raijua', 'Kab. Malaka'],
            'Kalimantan Barat' => ['Kota Pontianak', 'Kota Singkawang', 'Kab. Sambas', 'Kab. Bengkayang', 'Kab. Landak', 'Kab. Mempawah', 'Kab. Sanggau', 'Kab. Ketapang', 'Kab. Sintang', 'Kab. Kapuas Hulu', 'Kab. Sekadau', 'Kab. Melawi', 'Kab. Kayong Utara', 'Kab. Kubu Raya'],
            'Kalimantan Tengah' => ['Kota Palangka Raya', 'Kab. Kotawaringin Barat', 'Kab. Kotawaringin Timur', 'Kab. Kapuas', 'Kab. Barito Selatan', 'Kab. Barito Utara', 'Kab. Barito Timur', 'Kab. Murung Raya', 'Kab. Pulang Pisau', 'Kab. Gunung Mas', 'Kab. Seruyan', 'Kab. Katingan', 'Kab. Sukamara', 'Kab. Lamandau'],
            'Kalimantan Selatan' => ['Kota Banjarmasin', 'Kota Banjarbaru', 'Kab. Banjar', 'Kab. Tanah Laut', 'Kab. Tanah Bumbu', 'Kab. Kotabaru', 'Kab. Tapin', 'Kab. Hulu Sungai Selatan', 'Kab. Hulu Sungai Tengah', 'Kab. Hulu Sungai Utara', 'Kab. Tabalong', 'Kab. Barito Kuala', 'Kab. Balangan'],
            'Kalimantan Timur' => ['Kota Samarinda', 'Kota Balikpapan', 'Kota Bontang', 'Kab. Kutai Kartanegara', 'Kab. Kutai Barat', 'Kab. Kutai Timur', 'Kab. Berau', 'Kab. Paser', 'Kab. Penajam Paser Utara', 'Kab. Mahakam Ulu'],
            'Kalimantan Utara' => ['Kota Tarakan', 'Kab. Bulungan', 'Kab. Malinau', 'Kab. Nunukan', 'Kab. Tana Tidung'],
            'Sulawesi Utara' => ['Kota Manado', 'Kota Bitung', 'Kota Tomohon', 'Kota Kotamobagu', 'Kab. Minahasa', 'Kab. Minahasa Utara', 'Kab. Minahasa Selatan', 'Kab. Minahasa Tenggara', 'Kab. Bolaang Mongondow', 'Kab. Bolaang Mongondow Utara', 'Kab. Bolaang Mongondow Selatan', 'Kab. Bolaang Mongondow Timur', 'Kab. Kepulauan Sangihe', 'Kab. Kepulauan Talaud', 'Kab. Kepulauan Siau Tagulandang Biaro'],
            'Sulawesi Tengah' => ['Kota Palu', 'Kab. Donggala', 'Kab. Poso', 'Kab. Toli-Toli', 'Kab. Buol', 'Kab. Banggai', 'Kab. Banggai Kepulauan', 'Kab. Banggai Laut', 'Kab. Morowali', 'Kab. Morowali Utara', 'Kab. Parigi Moutong', 'Kab. Tojo Una-Una', 'Kab. Sigi'],
            'Sulawesi Selatan' => ['Kota Makassar', 'Kota Parepare', 'Kota Palopo', 'Kab. Gowa', 'Kab. Takalar', 'Kab. Maros', 'Kab. Pangkep', 'Kab. Barru', 'Kab. Bone', 'Kab. Soppeng', 'Kab. Wajo', 'Kab. Sidrap', 'Kab. Pinrang', 'Kab. Enrekang', 'Kab. Luwu', 'Kab. Luwu Utara', 'Kab. Luwu Timur', 'Kab. Tana Toraja', 'Kab. Toraja Utara', 'Kab. Bulukumba', 'Kab. Bantaeng', 'Kab. Jeneponto', 'Kab. Selayar', 'Kab. Sinjai'],
            'Sulawesi Tenggara' => ['Kota Kendari', 'Kota Bau-Bau', 'Kab. Konawe', 'Kab. Konawe Selatan', 'Kab. Konawe Utara', 'Kab. Konawe Kepulauan', 'Kab. Kolaka', 'Kab. Kolaka Utara', 'Kab. Kolaka Timur', 'Kab. Muna', 'Kab. Muna Barat', 'Kab. Buton', 'Kab. Buton Utara', 'Kab. Buton Selatan', 'Kab. Buton Tengah', 'Kab. Wakatobi', 'Kab. Bombana'],
            'Gorontalo' => ['Kota Gorontalo', 'Kab. Gorontalo', 'Kab. Gorontalo Utara', 'Kab. Bone Bolango', 'Kab. Boalemo', 'Kab. Pohuwato'],
            'Sulawesi Barat' => ['Kab. Mamuju', 'Kab. Mamuju Tengah', 'Kab. Mamasa', 'Kab. Polewali Mandar', 'Kab. Majene', 'Kab. Pasangkayu'],
            'Maluku' => ['Kota Ambon', 'Kota Tual', 'Kab. Maluku Tengah', 'Kab. Maluku Tenggara', 'Kab. Maluku Tenggara Barat', 'Kab. Buru', 'Kab. Buru Selatan', 'Kab. Seram Bagian Barat', 'Kab. Seram Bagian Timur', 'Kab. Kepulauan Aru', 'Kab. Kepulauan Tanimbar'],
            'Maluku Utara' => ['Kota Ternate', 'Kota Tidore Kepulauan', 'Kab. Halmahera Barat', 'Kab. Halmahera Tengah', 'Kab. Halmahera Utara', 'Kab. Halmahera Selatan', 'Kab. Halmahera Timur', 'Kab. Kepulauan Sula', 'Kab. Pulau Morotai', 'Kab. Pulau Taliabu'],
            'Papua' => ['Kota Jayapura', 'Kab. Jayapura', 'Kab. Merauke', 'Kab. Boven Digoel', 'Kab. Mappi', 'Kab. Asmat', 'Kab. Keerom', 'Kab. Sarmi', 'Kab. Mamberamo Raya'],
            'Papua Barat' => ['Kota Sorong', 'Kab. Sorong', 'Kab. Raja Ampat', 'Kab. Manokwari', 'Kab. Manokwari Selatan', 'Kab. Teluk Bintuni', 'Kab. Teluk Wondama'],
            'Papua Selatan' => ['Kab. Merauke', 'Kab. Boven Digoel', 'Kab. Mappi', 'Kab. Asmat'],
            'Papua Tengah' => ['Kab. Nabire', 'Kab. Paniai', 'Kab. Mimika', 'Kab. Puncak Jaya', 'Kab. Puncak', 'Kab. Deiyai', 'Kab. Dogiyai', 'Kab. Intan Jaya'],
            'Papua Pegunungan' => ['Kab. Jayawijaya', 'Kab. Pegunungan Bintang', 'Kab. Yahukimo', 'Kab. Tolikara', 'Kab. Mamberamo Tengah', 'Kab. Yalimo', 'Kab. Lanny Jaya', 'Kab. Nduga'],
            'Papua Barat Daya' => ['Kota Sorong', 'Kab. Sorong Selatan', 'Kab. Maybrat', 'Kab. Tambrauw', 'Kab. Kaimana'],
        ];

        return $data[$province] ?? [];
    }
}
