<?php

namespace Modules\Lpj\Database\Seeders;

use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Modules\Lpj\Models\Inspeksi;
use Modules\Basicdata\Models\Branch;
use Modules\Lpj\Models\DokumenJaminan;
use Modules\Lpj\Models\Permohonan;
use DateTime;

class MigrationGambarInspeksiSeeder extends Seeder
{
    /**
     * Run the database seeds.
     */
    protected $errorLogFile = __DIR__ . '/csv/inspeksi/foto_20251014-error.csv';
    /**
     * Migrasi data gambar inspeksi dari file csv ke tabel inspeksi_gambar
     *
     * @return void
     */
    public function run()
    {
        $this->initializeErrorLog();
        // Path ke file csv
        $filePath = realpath(__DIR__ . '/csv/inspeksi/foto_20251014.csv');

        if (!$filePath) {
            Log::error('File csv tidak ditemukan: ' . __DIR__ . '/csv/inspeksi/foto_20251014.csv');
            $this->command->error('File csv tidak ditemukan.');
            return;
        }

        if (($handle = fopen($filePath, 'r')) === false) {
            Log::error('Gagal membuka file CSV: ' . $filePath);
            $this->command->error('Gagal membuka file CSV.');
            return;
        }

        $header = fgetcsv($handle, 0, ',');
        $rows = [];
        $batchSize = 500;
        $userData = [];
        $branchCache = []; // <-- Gunakan sebagai cache
        $totalData = 0;

        while (($data = fgetcsv($handle, 0, ',')) !== false) {
            $totalData++;
        }

        rewind($handle);
        fgetcsv($handle, 0, ','); // Skip header

        $batchCount = 0;
        $currentRow = 0;
        $errorCount = 0;
        $errorDebitureIds = [];

        while (($data = fgetcsv($handle, 0, ',')) !== false) {
            if (count($data) != count($header)) {
                Log::warning('Baris CSV memiliki jumlah kolom yang tidak sesuai: ' . json_encode($data));
                continue;
            }

            $rows[] = array_combine($header, $data);
            $currentRow++;

            if (count($rows) >= $batchSize) {
                $batchCount++;
                $this->command->info("Memproses batch ke-{$batchCount} ({$currentRow}/{$totalData})");
                $this->processBatch($rows, $branchCache, $userData, $errorCount, $errorDebitureIds, $totalData, $batchCount, $currentRow);
                $rows = [];
            }
        }
        // info_harga_laporan_202505021522.csv
        // print_r($rows[0]);
        if (!empty($rows)) {
            $batchCount++;
            $this->command->info("Memproses batch ke-{$batchCount} ({$currentRow}/{$totalData})");
            $this->processBatch($rows, $branchCache, $userData, $errorCount, $errorDebitureIds, $totalData, $batchCount, $currentRow);
        }

        fclose($handle);
        $this->command->info("Data debiture berhasil dimigrasikan. Total data: {$totalData}, Total batch: {$batchCount}");
    }

    private function processBatch(array $rows, array &$branchCache, array &$userData, int &$errorCount, array &$errorDebitureIds, int $totalData, int $batchCount, int $currentRow)
    {
        // Kelompokkan berdasarkan mig_nomor_jaminan
        $groupedRows = $this->groupRowsByJaminan($rows);

        foreach ($groupedRows as $nomorJaminan => $groupRows) {
            try {
                // Ambil informasi permohonan dan dokument_id
                $nomorRegis = $this->getNomorRegistrasiPermohonan($nomorJaminan, $branchCache);
                if (!$nomorRegis) {
                    Log::warning("Nomor registrasi tidak ditemukan untuk nomor jaminan: {$nomorJaminan}");
                    $errorCount++;
                    $errorDebitureIds[] = $nomorJaminan;
                    continue;
                }

                // Bangun JSON foto_form
                $fotoJson = $this->checkFoto($groupRows);


                Inspeksi::updateOrCreate(
                    [
                        'permohonan_id' => $nomorRegis['id'],
                        'dokument_id' => $nomorRegis['dokument_id']
                    ],
                    [
                        'foto_form' => $fotoJson,
                        'updated_at' => now()
                    ]
                );

                $this->command->info("Berhasil update foto_form untuk nomor jaminan: {$nomorJaminan}");

            } catch (\Exception $e) {
                Log::error("Error pada nomor jaminan {$nomorJaminan}: " . $e->getMessage());
                $errorCount++;
                $errorDebitureIds[] = $nomorJaminan;
                continue;
            }
        }
    }
    private function groupRowsByJaminan(array $rows): array
    {
        $grouped = [];

        foreach ($rows as $row) {
            $nomorJaminan = $row['mig_nomor_jaminan'] ?? null;

            if (!empty($nomorJaminan)) {
                $grouped[$nomorJaminan][] = $row;
            }
        }

        return $grouped;
    }





    private function checkFoto(array $rows)
    {
        // Inisialisasi kelompok untuk tiap kategori
        $kategoriPrioritas = [
            'PETA LOKASI'                 => [],
            'GAMBAR SITUASI / SURAT UKUR' => [],
            'FOTO JAMINAN'                => [],
            'MAK'                         => [],
            'lainnya'                     => []
        ];

        foreach ($rows as $row) {
            // Ambil kolom penting
            $namaFoto      = trim($row['mig_nama_gambar'] ?? '');
            $pathFoto      = trim($row['mig_url_gambar'] ?? '');
            $kategori      = trim($row['mig_kategori'] ?? 'lainnya');
            $urutan        = (int)($row['mig_urutan_gambar'] ?? 999);
            $tgl           = trim($row['mig_tgl'] ?? '');
            $nomorLpj      = trim($row['mig_nomor_laporan'] ?? '');

            if (empty($pathFoto) || empty($tgl)) {
                continue; // Lewati jika tidak lengkap
            }

            try {
                $tanggal = \Carbon\Carbon::createFromFormat('d/m/Y H:i:s', $tgl)->startOfDay();
                if (!$tanggal) {
                    throw new \Exception("Tanggal tidak valid");
                }
            } catch (\Exception $e) {
                continue; // Lewati jika tanggal tidak valid
            }

            $tahun         = $tanggal->format('Y');
            $bulanAngka    = $tanggal->format('n');
            $bulanNama     = [
                1 => 'JANUARI', 2 => 'FEBRUARI', 3 => 'MARET',
                4 => 'APRIL', 5 => 'MEI', 6 => 'JUNI',
                7 => 'JULI', 8 => 'AGUSTUS', 9 => 'SEPTEMBER',
                10 => 'OKTOBER', 11 => 'NOVEMBER', 12 => 'DESEMBER'
            ][(int)$bulanAngka] ?? 'UNKNOWN';

            $tanggalFormat = $tanggal->format('dmY');

            if (empty($namaFoto)) {
                $namaFoto = basename($pathFoto) ?: 'image.jpg';
            }

            // Gunakan '/' sebagai separator path
            $finalPath = "surveyor/{$tahun}/{$bulanNama}/{$tanggalFormat}/{$nomorLpj}/{$pathFoto}";

            $fotoItem = [
                'urutan' => $urutan,
                'name' => $namaFoto,
                'path' => $finalPath,
                'category' => $kategori,
                'sub' => null,
                'description' => '',
                'created_by' => null,
                'created_at' => null
            ];

            // Masukkan ke dalam kelompok kategori
            if (isset($kategoriPrioritas[$kategori])) {
                $kategoriPrioritas[$kategori][] = $fotoItem;
            } else {
                $kategoriPrioritas['lainnya'][] = $fotoItem;
            }
        }

        // Urutkan masing-masing kategori berdasarkan urutan
        foreach ($kategoriPrioritas as &$kelompok) {
            usort($kelompok, function ($a, $b) {
                return $a['urutan'] <=> $b['urutan'];
            });
        }

        // Gabungkan dengan urutan prioritas: PETA LOKASI -> GAMBAR SITUASI -> FOTO JAMINAN -> lainnya
        $finalFotos = array_merge(
            $kategoriPrioritas['PETA LOKASI'],
            $kategoriPrioritas['GAMBAR SITUASI / SURAT UKUR'],
            $kategoriPrioritas['FOTO JAMINAN'],
            $kategoriPrioritas['lainnya']
        );

        // Hapus indeks 'urutan'
        $finalFotos = array_map(function ($foto) {
            unset($foto['urutan']);
            return $foto;
        }, $finalFotos);

        return json_encode([
            'upload_foto' => $finalFotos
        ], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
    }
    private function getNomorRegistrasiPermohonan($nomor_jaminan_id, array &$cache)
    {
        // Cek apakah sudah ada di cache
        if (isset($cache[$nomor_jaminan_id])) {
            return $cache[$nomor_jaminan_id];
        }

        // Cari di tabel Permohonan berdasarkan nomor registrasi
        $permohonan = Permohonan::where('nomor_registrasi', $nomor_jaminan_id)->first();

        if (!$permohonan) {
            // Tidak ditemukan
            $cache[$nomor_jaminan_id] = null;
            return null;
        }

        // Cari dokument jaminan terkait
        $dokumenJaminan = DokumenJaminan::where('permohonan_id', $permohonan->id)->first();

        // Simpan hasil ke cache
        $result = [
            'id' => $permohonan->id,
            'dokument_id' => $dokumenJaminan ? $dokumenJaminan->id : null
        ];

        $cache[$nomor_jaminan_id] = $result;

        return $result;
    }


    private function initializeErrorLog()
    {
        $file = $this->errorLogFile;

        if (file_exists($file)) {
            unlink($file); // Hapus file lama
        }

        $handle = fopen($file, 'w');
        fputcsv($handle, ['mig_kd_debitur_seq', 'Error']);
        fclose($handle);
    }

    private function logError(string $kode, string $message)
    {
        Log::error("Error migrasi dokumen jaminan [$kode]: $message");

        $handle = fopen($this->errorLogFile, 'a');
        fputcsv($handle, [$kode, $message]);
        fclose($handle);
    }
}
