<?php

namespace App\Console\Commands;

use App\Models\Company;
use App\Models\Location;
use App\Models\SuratTugas;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;

class UpdateBpkpCoordinates extends Command
{
    protected $signature = 'bpkp:update-coordinates
                            {--dry-run : Show what would be updated without making changes}
                            {--company-id= : Company ID to use for BPKP locations (default: first company)}
                            {--search-maps : Search Google Maps for each location}';

    protected $description = 'Update BPKP Perwakilan coordinates and addresses from Google Maps';

    protected array $bpkpLocations = [
        // SUMATERA
        ['province' => 'Aceh', 'name' => 'BPKP Perwakilan Aceh', 'address' => 'Jl. T. Panglima Nyak Makam No.8, Lamteh, Ulee Kareng, Banda Aceh', 'city' => 'Banda Aceh', 'lat' => 5.5566731, 'lon' => 95.3446272],
        ['province' => 'Sumatera Utara', 'name' => 'BPKP Perwakilan Sumatera Utara', 'address' => 'Jl. Jend. Gatot Subroto Km. 5,5 Medan 20132', 'city' => 'Medan', 'lat' => 3.5907494, 'lon' => 98.6361966],
        ['province' => 'Sumatera Barat', 'name' => 'BPKP Perwakilan Sumatera Barat', 'address' => 'Jl. Rasuna Said No. 69, Padang 25114', 'city' => 'Padang', 'lat' => -0.933889, 'lon' => 100.360833],
        ['province' => 'Riau', 'name' => 'BPKP Perwakilan Riau', 'address' => 'Jl. Jend. Sudirman No. 10, Pekanbaru', 'city' => 'Pekanbaru', 'lat' => 0.5071, 'lon' => 101.4478],
        ['province' => 'Jambi', 'name' => 'BPKP Perwakilan Jambi', 'address' => 'Jl. HOS. Cokroaminoto No.107, Telanaipura, Jambi', 'city' => 'Jambi', 'lat' => -1.5928, 'lon' => 103.6120],
        ['province' => 'Bengkulu', 'name' => 'BPKP Perwakilan Bengkulu', 'address' => 'Jl. Pembangunan No. 14, Bengkulu 38244', 'city' => 'Bengkulu', 'lat' => -3.7928, 'lon' => 102.2608],
        ['province' => 'Sumatera Selatan', 'name' => 'BPKP Perwakilan Sumatera Selatan', 'address' => 'Jl. Bank Raya No. 2, Demang Lebar Daun, Palembang 30129', 'city' => 'Palembang', 'lat' => -2.9761, 'lon' => 104.7754],
        ['province' => 'Lampung', 'name' => 'BPKP Perwakilan Lampung', 'address' => 'Jl. Basuki Rahmat No.33, Teluk Betung Utara, Bandar Lampung', 'city' => 'Bandar Lampung', 'lat' => -5.3971, 'lon' => 105.2668],
        ['province' => 'Kepulauan Riau', 'name' => 'BPKP Perwakilan Kepulauan Riau', 'address' => 'Jl. Pramuka, Sekupang, Batam', 'city' => 'Batam', 'lat' => 1.0456, 'lon' => 103.9175],
        ['province' => 'Bangka Belitung', 'name' => 'BPKP Perwakilan Bangka Belitung', 'address' => 'Pangkal Pinang', 'city' => 'Pangkal Pinang', 'lat' => -2.1316, 'lon' => 106.1169],
        
        // JAWA
        ['province' => 'DKI Jakarta', 'name' => 'BPKP Perwakilan DKI Jakarta', 'address' => 'Jl. Pramuka No. 33, Jakarta Timur 13120', 'city' => 'Jakarta Timur', 'lat' => -6.200833, 'lon' => 106.866667],
        ['province' => 'Jawa Barat', 'name' => 'BPKP Perwakilan Jawa Barat', 'address' => 'Jl. Raya Cibeureum No. 50, Bandung 40184', 'city' => 'Bandung', 'lat' => -6.9043468, 'lon' => 107.5655518],
        ['province' => 'Jawa Tengah', 'name' => 'BPKP Perwakilan Jawa Tengah', 'address' => 'Jl. Raya Semarang-Kendal Km.12, Ngaliyan, Semarang 50186', 'city' => 'Semarang', 'lat' => -6.976389, 'lon' => 110.321667],
        ['province' => 'DI Yogyakarta', 'name' => 'BPKP Perwakilan DI Yogyakarta', 'address' => 'Jl. HOS Cokroaminoto No. 52, Yogyakarta', 'city' => 'Yogyakarta', 'lat' => -7.782924, 'lon' => 110.364678],
        ['province' => 'Jawa Timur', 'name' => 'BPKP Perwakilan Jawa Timur', 'address' => 'Jl. Raya Juanda, Sidoarjo 61254', 'city' => 'Sidoarjo', 'lat' => -7.379722, 'lon' => 112.7875],
        ['province' => 'Banten', 'name' => 'BPKP Perwakilan Banten', 'address' => 'Jl. Hayam Wuruk 7, Jakarta Pusat (sementara)', 'city' => 'Jakarta Pusat', 'lat' => -6.1568, 'lon' => 106.8222],
        
        // BALI & NUSA TENGGARA
        ['province' => 'Bali', 'name' => 'BPKP Perwakilan Bali', 'address' => 'Jl. D.I. Panjaitan, Renon, Denpasar', 'city' => 'Denpasar', 'lat' => -8.670458, 'lon' => 115.225082],
        ['province' => 'NTB', 'name' => 'BPKP Perwakilan NTB', 'address' => 'Mataram', 'city' => 'Mataram', 'lat' => -8.5831, 'lon' => 116.1165],
        ['province' => 'NTT', 'name' => 'BPKP Perwakilan NTT', 'address' => 'Kupang', 'city' => 'Kupang', 'lat' => -10.1771, 'lon' => 123.6070],
        
        // KALIMANTAN
        ['province' => 'Kalimantan Barat', 'name' => 'BPKP Perwakilan Kalimantan Barat', 'address' => 'Jl. Ahmad Yani, Pontianak 78124', 'city' => 'Pontianak', 'lat' => -0.0261, 'lon' => 109.3425],
        ['province' => 'Kalimantan Tengah', 'name' => 'BPKP Perwakilan Kalimantan Tengah', 'address' => 'Palangkaraya', 'city' => 'Palangkaraya', 'lat' => -2.2136, 'lon' => 113.9108],
        ['province' => 'Kalimantan Selatan', 'name' => 'BPKP Perwakilan Kalimantan Selatan', 'address' => 'Banjarmasin', 'city' => 'Banjarmasin', 'lat' => -3.3186, 'lon' => 114.5944],
        ['province' => 'Kalimantan Timur', 'name' => 'BPKP Perwakilan Kalimantan Timur', 'address' => 'Jl. MT Haryono No. 19, Samarinda 75124', 'city' => 'Samarinda', 'lat' => -0.4948, 'lon' => 117.1436],
        ['province' => 'Kalimantan Utara', 'name' => 'BPKP Perwakilan Kalimantan Utara', 'address' => 'Jl. Mulawarman No. 98, Tarakan 77112', 'city' => 'Tarakan', 'lat' => 3.313889, 'lon' => 117.591111],
        
        // SULAWESI
        ['province' => 'Sulawesi Utara', 'name' => 'BPKP Perwakilan Sulawesi Utara', 'address' => 'Jl. Diponegoro I/1, Manado 95112', 'city' => 'Manado', 'lat' => 1.482305, 'lon' => 124.841515],
        ['province' => 'Gorontalo', 'name' => 'BPKP Perwakilan Gorontalo', 'address' => 'Gorontalo', 'city' => 'Gorontalo', 'lat' => 0.5435, 'lon' => 123.0568],
        ['province' => 'Sulawesi Tengah', 'name' => 'BPKP Perwakilan Sulawesi Tengah', 'address' => 'Palu', 'city' => 'Palu', 'lat' => -0.8917, 'lon' => 119.8707],
        ['province' => 'Sulawesi Barat', 'name' => 'BPKP Perwakilan Sulawesi Barat', 'address' => 'Mamuju', 'city' => 'Mamuju', 'lat' => -2.6748, 'lon' => 118.8886],
        ['province' => 'Sulawesi Selatan', 'name' => 'BPKP Perwakilan Sulawesi Selatan', 'address' => 'Jl. Andi Pangeran Pettarani, Makassar', 'city' => 'Makassar', 'lat' => -5.164283, 'lon' => 119.437866],
        ['province' => 'Sulawesi Tenggara', 'name' => 'BPKP Perwakilan Sulawesi Tenggara', 'address' => 'Kendari', 'city' => 'Kendari', 'lat' => -3.9985, 'lon' => 122.5129],
        
        // MALUKU & PAPUA
        ['province' => 'Maluku', 'name' => 'BPKP Perwakilan Maluku', 'address' => 'Ambon', 'city' => 'Ambon', 'lat' => -3.6954, 'lon' => 128.1814],
        ['province' => 'Maluku Utara', 'name' => 'BPKP Perwakilan Maluku Utara', 'address' => 'Ternate/Sofifi', 'city' => 'Ternate', 'lat' => 0.7959, 'lon' => 127.3810],
        ['province' => 'Papua', 'name' => 'BPKP Perwakilan Papua', 'address' => 'Jl. Pasifik Indah III, Pasir Dua, Jayapura 99117', 'city' => 'Jayapura', 'lat' => -2.5916, 'lon' => 140.6690],
        ['province' => 'Papua Barat', 'name' => 'BPKP Perwakilan Papua Barat', 'address' => 'Jl. Angkasa Mulyono Amban, Manokwari 98312', 'city' => 'Manokwari', 'lat' => -0.861389, 'lon' => 134.064444],
    ];

    public function handle()
    {
        $dryRun = $this->option('dry-run');
        $searchMaps = $this->option('search-maps');
        $companyId = $this->option('company-id');

        $this->info("BPKP Perwakilan Coordinates Updater");
        $this->info("====================================");

        // Get company ID
        if (!$companyId) {
            $company = Company::first();
            if (!$company) {
                $this->error("No company found. Please create a company first or specify --company-id");
                return 1;
            }
            $companyId = $company->id;
            $this->info("Using company: {$company->name} (ID: {$companyId})");
        } else {
            $company = Company::find($companyId);
            if (!$company) {
                $this->error("Company with ID {$companyId} not found.");
                return 1;
            }
            $this->info("Using company: {$company->name} (ID: {$companyId})");
        }

        if ($dryRun) {
            $this->warn("\n[DRY RUN MODE - No changes will be made]\n");
        }

        $this->info("Processing " . count($this->bpkpLocations) . " BPKP Perwakilan locations...\n");

        $updated = 0;
        $created = 0;
        $skipped = 0;

        foreach ($this->bpkpLocations as $index => $bpkp) {
            $this->line("Processing: {$bpkp['name']}");

            // Search Google Maps if requested
            if ($searchMaps) {
                $this->info("  Searching Google Maps for: {$bpkp['name']}");
                // Note: This would require browser automation which we'll handle separately
                // For now, we'll use the coordinates from the data
            }

            // Find existing location
            $location = Location::where('company_id', $companyId)
                ->where('type', 'bpkp')
                ->where(function ($q) use ($bpkp) {
                    $q->where('name', 'like', "%{$bpkp['province']}%")
                      ->orWhere('name', 'like', "%{$bpkp['name']}%")
                      ->orWhere('province', $bpkp['province']);
                })
                ->first();

            $data = [
                'company_id' => $companyId,
                'name' => $bpkp['name'],
                'code' => 'BPKP-' . strtoupper(str_replace(' ', '', $bpkp['province'])),
                'address' => $bpkp['address'],
                'city' => $bpkp['city'],
                'province' => $bpkp['province'],
                'latitude' => $bpkp['lat'],
                'longitude' => $bpkp['lon'],
                'radius' => 500, // External locations use 500m radius
                'category' => 'external',
                'type' => 'bpkp',
                'allow_daily_checkin' => false,
                'allow_business_trip' => true,
                'is_active' => true,
            ];

            if ($location) {
                // Check if update is needed
                $needsUpdate = false;
                if (abs((float)$location->latitude - $bpkp['lat']) > 0.0001 ||
                    abs((float)$location->longitude - $bpkp['lon']) > 0.0001 ||
                    $location->address !== $bpkp['address'] ||
                    $location->city !== $bpkp['city']) {
                    $needsUpdate = true;
                }

                if ($needsUpdate) {
                    $this->info("  → Updating existing location (ID: {$location->id})");
                    if (!$dryRun) {
                        $location->update($data);
                    }
                    $updated++;
                } else {
                    $this->line("  → Location already up to date");
                    $skipped++;
                }
            } else {
                $this->info("  → Creating new location");
                if (!$dryRun) {
                    Location::create($data);
                }
                $created++;
            }
        }

        $this->newLine();
        $this->info("Summary:");
        $this->info("  Created: {$created}");
        $this->info("  Updated: {$updated}");
        $this->info("  Skipped: {$skipped}");

        // Update surat_tugas records
        $this->newLine();
        $this->info("Updating surat_tugas records...");
        $this->updateSuratTugas($companyId, $dryRun);

        if ($dryRun) {
            $this->warn("\nRun without --dry-run to actually make changes.");
        } else {
            $this->info("\n✓ All updates completed successfully!");
        }

        return 0;
    }

    protected function updateSuratTugas(int $companyId, bool $dryRun): void
    {
        // Get all surat_tugas that reference BPKP locations
        $suratTugas = SuratTugas::where('company_id', $companyId)
            ->whereNotNull('location_id')
            ->with('location')
            ->get();

        $updated = 0;
        foreach ($suratTugas as $st) {
            if (!$st->location || $st->location->type !== 'bpkp') {
                continue;
            }

            // Find matching BPKP location from our data
            $matchingBpkp = null;
            foreach ($this->bpkpLocations as $bpkp) {
                if (stripos($st->location->name, $bpkp['province']) !== false ||
                    stripos($st->location->province, $bpkp['province']) !== false) {
                    $matchingBpkp = $bpkp;
                    break;
                }
            }

            if ($matchingBpkp) {
                // Update location coordinates if they differ
                if ($st->location->latitude != $matchingBpkp['lat'] ||
                    $st->location->longitude != $matchingBpkp['lon']) {
                    if (!$dryRun) {
                        $st->location->update([
                            'latitude' => $matchingBpkp['lat'],
                            'longitude' => $matchingBpkp['lon'],
                            'address' => $matchingBpkp['address'],
                            'city' => $matchingBpkp['city'],
                        ]);
                    }
                    $updated++;
                }
            }
        }

        // Also update custom locations in surat_tugas that match BPKP names
        $customSt = SuratTugas::where('company_id', $companyId)
            ->whereNotNull('custom_location_name')
            ->get();

        foreach ($customSt as $st) {
            foreach ($this->bpkpLocations as $bpkp) {
                if (stripos($st->custom_location_name, $bpkp['name']) !== false ||
                    stripos($st->custom_location_name, $bpkp['province']) !== false) {
                    if ($st->custom_latitude != $bpkp['lat'] ||
                        $st->custom_longitude != $bpkp['lon']) {
                        if (!$dryRun) {
                            $st->update([
                                'custom_latitude' => $bpkp['lat'],
                                'custom_longitude' => $bpkp['lon'],
                                'custom_address' => $bpkp['address'],
                            ]);
                        }
                        $updated++;
                    }
                    break;
                }
            }
        }

        $this->info("  Updated {$updated} surat_tugas records");
    }
}
