<?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 Modules\Location\Models\City;
use Modules\Location\Models\District;
use Modules\Location\Models\Province;
use Modules\Location\Models\Village;

// Load file helper
require_once __DIR__ . '/MigInspeksiHelper.php';
class MigrationInpseksiSeeder extends Seeder
{
    protected $errorLogFile = __DIR__ . '/csv/inspeksi/inspeksi.09_error.csv';
    /**
     * Properti command disediakan oleh Laravel saat seeder dijalankan melalui Artisan.
     * Dideklarasikan untuk menghindari error linter pada akses properti.
     *
     * @var mixed|null
     */
    protected $command;
    // protected $fielKesimpulan = ;
    /**
     * Run the database seeds.
     */
    public function run()
    {
        $this->initializeErrorLog();
        // Path ke file csv
        $filePath = realpath(__DIR__ . '/csv/inspeksi/inspeksi.09.csv');

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

         if (($handle = fopen($filePath, 'r')) === false) {
            Log::error('Gagal membuka file CSV: ' . $filePath);
            \Illuminate\Support\Facades\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 = [];
            }
        }

        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 &$debitureCache,
    int &$errorCount,
    array &$errorDebitureIds,
    int $totalData,
    int $batchCount,
    int $currentRow
) {
    // Kelompokkan baris berdasarkan mig_nomor_jaminan
    $groupedData = $this->groupRowsByJaminan($rows);

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

            // Cek apakah sudah ada data
            $existingRecord = Inspeksi::where('permohonan_id', $nomorRegis['id'])
                ->where('dokument_id', $nomorRegis['dokument_id'])
                ->whereNotNull('data_form')
                ->first();

            if ($existingRecord) {
                //$this->command->info("Data untuk nomor jaminan {$nomorJaminan} sudah ada. Lewati...");
                //continue;
            }

            // Ambil baris pertama untuk created_at/updated_at
            $firstRow = reset($groupRows);

            // Bangun JSON lengkap
            $dataFormJson = $this->buildFullDataForm($groupRows);
            $jenisJaminan = $this->checkJenisJaminan($groupRows[0]['mig_name'] ?? '');

            if (!$dataFormJson) {
                Log::warning("Data form kosong untuk nomor jaminan: {$nomorJaminan}");
                $errorCount++;
                $errorDebitureIds[] = $nomorJaminan;
                continue;
            }

            // Bangun JSON terkelompok berdasarkan mig_jenis_legalitas_jaminan_name
            $groupedLegalitasJson = $this->buildGroupedLegalitas($groupRows);


            Log::info("Grouped legalitas JSON dibangun untuk nomor jaminan {$nomorJaminan}.", ['length' => strlen($groupedLegalitasJson ?? '')]);

            // Gunakan transaksi saat menyimpan
            DB::beginTransaction();
            Inspeksi::updateOrCreate([
                'permohonan_id' => $nomorRegis['id'] ?? null,
                'dokument_id' => $nomorRegis['dokument_id'] ?? null,
            ],[
                'name' => $jenisJaminan,
                'data_form' => $dataFormJson,
                'foto_form' => null,
                'data_pembanding' => null,
                'permohonan_id' => $nomorRegis['id'] ?? null,
                'dokument_id' => $nomorRegis['dokument_id'] ?? null,
                'created_at' => $this->parseTimestamp($firstRow['created_at'] ?? null),
                'updated_at' => $this->parseTimestamp($firstRow['updated_at'] ?? null),
                'nomor_lpj' => $nomorJaminan,
                'processed_at' => now(),
                'mig_detail_data_jaminan' => $this->kv_to_json($groupRows[0]['alamat_bundle'] ?? null),
                'mig_detail_legalitas_jaminan' => $groupedLegalitasJson,
                'is_mig' => 1
            ]);
            DB::commit();

            $this->command->info("Berhasil simpan data inspeksi untuk nomor jaminan: {$nomorJaminan}");

        } catch (\Exception $e) {
            DB::rollBack();
            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 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 buildFullDataForm(array $rows)
{
    if (empty($rows)) {
        return null;
    }

    $jenisJaminan = $rows[0]['mig_name'] ?? null;

    if (!$jenisJaminan) {
        return null;
    }

    try {
        $jsonResult = $this->checkBuildJson($jenisJaminan, $rows);
        // Validasi apakah hasil JSON valid
        json_decode($jsonResult);
        return $jsonResult;
    } catch (\Exception $e) {
        Log::error("Gagal build JSON untuk jenis jaminan {$jenisJaminan}: " . $e->getMessage());
        return null;
    }
}


    private function loadKesimpulanByNomorLpj($nomorLpj)
    {
        $filePath = realpath(__DIR__ . '/csv/inspeksi/kesimpulan.09.csv');

        if (!$filePath || !$nomorLpj) {
            return [];
        }

        if (($handle = fopen($filePath, 'r')) === false) {
            Log::error("Gagal membuka file CSV kesimpulan: " . $filePath);
            return [];
        }

        $header = fgetcsv($handle, 0, ',');
        $result = [];

        while (($data = fgetcsv($handle, 0, ',')) !== false) {
            if (count($data) != count($header)) {
                continue;
            }

            $row = array_combine($header, $data);

            if ($row['mig_nomor_lpj'] === $nomorLpj) {
                $result[] = $row;
            }
        }

        fclose($handle);

        return $result;
    }



    private function checkLingkungan($rows)
    {
        $dataToInsertJson = [];

        // Inisialisasi struktur lingkungan
        $lingkungan = [
            'jarak_jalan_utama' => null,
            'jalan_linkungan' => null,
            'jarak_cbd_point' => null,
            'nama_cbd_point' => null,
            'lebar_perkerasan_jalan' => null,
            'perkerasan_jalan' => ['perkerasan_jalan' => [], 'lainnya' => null],
            'lalu_lintas' => null,
            'gol_mas_sekitar' => [],
            'tingkat_keramaian' => [],
            'terletak_diarea' => ['terletak_diarea' => [], 'lainnya' => null],
            'disekitar_lokasi' => null,
            'kondisi_bagunan_disekitar_lokasi' => null,
            'sifat_bagunan_disekitar_lokasi' => null,
            'dekat_makam' => 'tidak',
            'jarak_makam' => null,
            'nama_makam' => null,
            'dekat_tps' => 'tidak',
            'jarak_tps' => null,
            'nama_tps' => null,
            'dekat_lainnya' => null,
            'merupakan_daerah' => [],
            'fasilitas_dekat_object' => [],
            'fasilitas_dekat_object_input' => [
                'Tempat Ibadah' => null,
                'Rumah Sakit' => null,
                'Sekolah' => null,
                'Kantor Pemerintahan' => null,
                'Stasiun Kereta' => null,
                'Terminal Bus' => null,
                'Bandara' => null,
                'Pos Polisi' => null,
                'Lainnya' => null
            ]
        ];

        foreach ($rows as $row) {
            $name = trim($row['name']);
            $value = !empty($row['mig_name_keterangan_lain']) ? $row['mig_name_keterangan_lain'] : $row['mig_name_keterangan'];

            switch ($name) {
                case 'Lebar jalan dimuka lokasi':
                    $lingkungan['lebar_perkerasan_jalan'] = $row['mig_name_keterangan_lain'];
                    break;

                case 'Lapisan perkerasan jalan dari':
                    if ($value === 'Lainnya') {
                        $lingkungan['perkerasan_jalan']['perkerasan_jalan'][] = $value;
                        $lingkungan['perkerasan_jalan']['lainnya'] = $row['mig_name_keterangan_lain'];
                    } else {
                        $lingkungan['perkerasan_jalan']['perkerasan_jalan'][] = $value;
                    }
                    break;

                case 'Lalulintas didepan lokasi':
                    $lingkungan['lalu_lintas'] = $value;
                    break;

                case 'Golongan Masyarakat sekitar':
                    $lingkungan['gol_mas_sekitar'][] = $value;
                    break;

                case 'Dengan kondisi':
                    $lingkungan['tingkat_keramaian'][] = $value;
                    break;

                case 'Terletak didaerah':
                    if ($value === 'Lainnya') {
                        $lingkungan['terletak_diarea']['terletak_diarea'][] = $value;
                        $lingkungan['terletak_diarea']['lainnya'] = $row['mig_name_keterangan_lain'];
                    } else {
                        $lingkungan['terletak_diarea']['terletak_diarea'][] = $value;
                    }
                    break;

                case 'Disekitar lokasi':
                    $lingkungan['disekitar_lokasi'] = $value === 'Telah ada bangunan' ? 'sesuai' : 'tidak sesuai';
                    break;

                case 'Merupakan daerah':
                    $lingkungan['merupakan_daerah'][] = $value;
                    break;

                case 'Fasilitas umum dekat lokasi':
                    $lingkungan['fasilitas_dekat_object'][] = $value;
                    if (isset($lingkungan['fasilitas_dekat_object_input'][$value])) {
                        $lingkungan['fasilitas_dekat_object_input'][$value] = $value;
                    } elseif ($value === 'Pasar / Swalayan') {
                        $lingkungan['fasilitas_dekat_object_input']['Lainnya'] = 'pasar';
                    }
                    break;
            }
        }

        // Isi default jika kosong
        if (empty($lingkungan['fasilitas_dekat_object'])) {
            $lingkungan['fasilitas_dekat_object'] = [];
        }

        // Masukkan ke array JSON
        $dataToInsertJson[] = json_encode([
            'lingkungan' => $lingkungan
        ], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);

        return $dataToInsertJson;
    }

    private function checkAsset(array $rows)
    {
        $dataToInsertJson = [];

        // Ambil baris pertama saja
        $firstRow = reset($rows);

        if (!$firstRow) {
            return [];
        }

        // Inisialisasi variabel dari baris pertama
        $hubCadeb = null;
        $hubPenghuni = null;
        $jenisAsset = null;

        // Ambil data utama dari baris pertama
        $pihakBank = $firstRow['mig_pihak_bank'] ?? null;
        $debiturPerwakilan = $firstRow['mig_debiture_perwakilan'] ?? null;
        $address = $firstRow['address'] ?? null;

        // Kode wilayah
        $provinceCache = []; // cache untuk helper
        $cityCache = [];
        $districtCache = [];
        $subdistrictCache = [];

        $proviceCode = $this->getProvinceCode($firstRow['mig_province_name'] ?? '', $provinceCache);
        $cityCode = $this->getCityCode($firstRow['mig_city_name'] ?? '', $cityCache);
        $districtCode = $this->getDistrictCode($firstRow['mig_district_name'] ?? '', $districtCache);
        $subdistrict = $this->getSubdistrictCode($firstRow['mig_village_name'] ?? '', $subdistrictCache, $districtCache);

        // Proses hubungan pemilik/penghuni & jenis asset dari seluruh rows
        foreach ($rows as $row) {
            $name = trim($row['name'] ?? '');
            $keySesuaiORTidak = !empty($row['mig_name_keterangan_lain']) ? 'sesuai' : 'tidak sesuai';
            $value = !empty($row['mig_name_keterangan_lain'])
                        ? $row['mig_name_keterangan_lain']
                        : $row['mig_name_keterangan'] ?? null;

            switch ($name) {
                case 'Hubungan Pemilik Jaminan dengan Debitur':
                    $hubCadeb = [
                        $keySesuaiORTidak => $value
                    ];
                    break;

                case 'Hubungan Penghuni Jaminan dengan Debitur':
                    $hubPenghuni = [
                        $keySesuaiORTidak => $value
                    ];
                    break;

                case 'Jenis Bangunan':
                    $jenisAsset = [
                        $keySesuaiORTidak => $value
                    ];
                    break;
            }
        }

        // Isi default jika kosong
        if (empty($hubCadeb)) {
            $hubCadeb = ["tidak sesuai" => null];
        }
        if (empty($hubPenghuni)) {
            $hubPenghuni = ["tidak sesuai" => null];
        }
        if (empty($jenisAsset)) {
            $jenisAsset = ["sesuai" => null];
        }

        // Bangun struktur JSON
        $asset = [
            "debitur_perwakilan" => $debiturPerwakilan,
            "jenis_asset" => $jenisAsset,
            "alamat" => [
                "sesuai" => [
                    "address" => $address,
                    "village_code" => $subdistrict['code'],
                    "district_code" => $districtCode,
                    "city_code" => $cityCode,
                    "province_code" => $proviceCode
                ]
            ],
            "hub_cadeb" => $hubCadeb,
            "hub_cadeb_penghuni" => $hubPenghuni,
            "pihak_bank" => $pihakBank,
            "kordinat_lng" => null,
            "kordinat_lat" => null
        ];

        // Masukkan ke array JSON
        $dataToInsertJson[] = json_encode([
            "asset" => $asset
        ], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);

        return $dataToInsertJson;
    }


    private function checkKesimpulan($rows)
    {
        $dataToInsertJson = [];

        $fakta = [
            'fakta_positif' => [],
            'fakta_negatif' => [],
            'rute_menuju' => null,
            'batas_batas' => ["Utara", "Timur", "Selatan", "Barat"],
            'batas_batas_input' => [
                "Utara" => null,
                "Timur Laut" => null,
                "Timur" => null,
                "Tenggara" => null,
                "Selatan" => null,
                "Barat Daya" => null,
                "Barat" => null,
                "Barat Laut" => null,
                "Utara Timur Laut" => null,
                "Timur Timur Laut" => null,
                "Timur Tenggara" => null,
                "Selatan Tenggara" => null,
                "Selatan Barat Daya" => null,
                "Barat Barat Daya" => null,
                "Barat Barat Laut" => null,
                "Utara Barat Laut" => null
            ],
            'kondisi_lingkungan' => [],
            'kondisi_lain_bangunan' => [],
            'informasi_dokument' => [],
            'peruntukan' => null,
            'kdb' => null,
            'kdh' => null,
            'gsb' => null,
            'max_lantai' => null,
            'klb' => null,
            'gss' => null,
            'pelebaran_jalan' => null,
            'nama_petugas' => null,
            'keterangan' => [],
            'saran' => []
        ];

        foreach ($rows as $row) {
            $jenis      = trim($row['mig_keterangan']); // misal: Fakta Positif, Fakta Negatif, dll
            $keterangan = trim($row['mig_kesimpulan']);

            switch ($jenis) {
                case 'Faktor Positif':
                    $fakta['fakta_positif'][] = $keterangan;
                    break;

                case 'Faktor Negatif':
                    $fakta['fakta_negatif'][] = $keterangan;
                    break;

                case 'Rute Menuju':
                    $fakta['rute_menuju'] = $keterangan;
                    break;

                case 'Kondisi Lingkungan':
                    $fakta['kondisi_lingkungan'][] = $keterangan;
                    break;

                case 'Kondisi Bangunan':
                    $fakta['kondisi_lain_bangunan'][] = $keterangan;
                    break;

                case 'Lain - lain':
                    $fakta['informasi_dokument'][] = $keterangan;
                    break;

                case 'CATATAN YANG PERLU DIPERHATIKAN':
                    $fakta['keterangan']['CATATAN YANG PERLU DIPERHATIKAN'][] = $keterangan;
                    break;
                case 'Catatan':
                    $fakta['keterangan']['Catatan'][] = $keterangan;
                    break;
                case 'Saran':
                    $fakta['saran'][] = $keterangan;
                    break;
            }
        }


        $dataToInsertJson[] = json_encode([
            'fakta' => $fakta
        ], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);

        return $dataToInsertJson;
    }

    private function parseTimestamp(?string $timestamp): ?string
    {
        try {
            if ($timestamp) {
                // Cek jika format hanya tanggal (Y-m-d)
                if (preg_match('/^\d{4}-\d{2}-\d{2}$/', $timestamp)) {
                    return \Carbon\Carbon::createFromFormat('Y-m-d', $timestamp)
                        ->startOfDay()
                        ->toDateTimeString();
                }
                // Format lengkap (Y-m-d H:i:s)
                if (preg_match('/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/', $timestamp)) {
                    return \Carbon\Carbon::createFromFormat('Y-m-d H:i:s', $timestamp)->toDateTimeString();
                }
                // Format d/m/Y H:i:s (contoh: 28/4/2047 14:43:43)
                if (preg_match('/^\d{1,2}\/\d{1,2}\/\d{4} \d{2}:\d{2}:\d{2}$/', $timestamp)) {
                    return \Carbon\Carbon::createFromFormat('d/m/Y H:i:s', $timestamp)->toDateTimeString();
                }
            }
            return null;
        } catch (\Exception $e) {
            Log::error('Gagal memparsing timestamp: ' . $timestamp . '. Pesan: ' . $e->getMessage());
            return null;
        }
    }

    private function getProvinceCode(string $name, array &$cache): ?string
    {

        $normalizedName = strtolower($name);
        if (isset($cache[$normalizedName])) {
            return $cache[$normalizedName];
        }

        $province = Province::whereRaw('LOWER(name) = ?', [strtolower($name)])->first();

        if ($province) {
            $cache[$normalizedName] = $province->code;
            return $province->code;
        }

        return null;
    }

    private function getCityCode(string $name, array &$cache): ?string
    {
        $normalizedName = strtolower($name);
        if (isset($cache[$normalizedName])) {
            return $cache[$normalizedName];
        }

        $city = City::whereRaw('LOWER(name) = ?', [strtolower($name)])->first();

        if ($city) {
            $cache[$normalizedName] = $city->code;
            return $city->code;
        }

        return null;
    }

    private function getDistrictCode(string $name, array &$cache): ?string
    {
        $normalizedName = strtolower($name);
        if (isset($cache[$normalizedName])) {
            return $cache[$normalizedName];
        }

        $district = District::whereRaw('LOWER(name) = ?', [strtolower($name)])->first();

        if ($district) {
            $cache[$normalizedName] = $district->code;
            return $district->code;
        }

        return null;
    }

    private function getSubdistrictCode(string $name, array &$cache, array &$districtCache): ?array
    {
        $normalizedName = strtolower($name);

        // Pastikan cache menyimpan array, bukan hanya kode
        if (isset($cache[$normalizedName])) {
            return $cache[$normalizedName];
        }

        // Ambil subdistrict dari database
        $subdistrict = Village::whereRaw('LOWER(name) = ?', [$normalizedName])->first();

        // Jika ditemukan, simpan ke dalam cache sebagai array lengkap
        if ($subdistrict) {
            $cache[$normalizedName] = [
                'code' => $subdistrict->code,
                'postal_code' => $subdistrict->postal_code
            ];
            return $cache[$normalizedName];
        }

        // Jika tidak ditemukan, kembalikan null
        return [
            'code' => null,
            'postal_code' => null
        ];
    }

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

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

        // Buat file baru dengan header
        $handle = fopen($file, 'w');
        fputcsv($handle, ['mig_mst_jaminan_nomor_jaminan', 'Error']);
        fclose($handle);
    }

    private function logError($nomorJaminan, string $message)
    {
        Log::error("Error migrasi permohonan [$nomorJaminan]: $message");

        // Tulis ke file error
        $handle = fopen($this->errorLogFile, 'a');
        fputcsv($handle, [$nomorJaminan, $message]);

    }


    public function checkJenisJaminan($input)
    {
        $input = trim($input);
        switch ($input) {
            case 'Tanah dan Bangunan eks KPR-BPPN':
                return 'tanah, bangunan, lingkungan, fakta, informasi';
            case 'Pabrik':
                return 'tanah, bangunan, lingkungan, fakta, informasi';
            case 'Kapal Laut':
                return 'kapal-laut';

            case 'Tanah dan/atau Bangunan':
                return 'tanah, bangunan';

            case 'Kendaraan Bermotor':
                return 'kendaraan-';

            case 'Mesin-mesin dan Peralatan':
                return 'mesin';

            case 'Barang Dagangan/FEO':
                return 'barang-dagangan';

            case 'Pesawat Udara':
                return 'pesawat-udara';

            case 'Alat Berat':
                return 'alat-berat';

            case 'Deposito':
                return 'deposito';

            case 'Rekening Giro / Tabungan':
                return 'rekening-giro-tabungan';

            case 'Emas':
                return 'emas';

            case 'Jaminan Pribadi / Personal Guarantee':
                return 'jaminan-pribadi';

            case 'Jaminan Perusahaan / Corporate Guarantee':
                return 'jaminan-perusahaan';

            case 'Resi Gudang':
                return 'resi-gudang';

            case 'Surat Berharga dan Saham':
                return 'surat-berharga-saham';

            case 'Tanah dan Bangunan (KerjaSama)':
                return 'tanah-bangunan-kerja-sama';

            case 'Tanah Kavling (Kerjasama)':
                return 'tanah-kavling';

            case 'Persediaan Barang / Barang Dagangan':
                return 'persediaan-barang';

            case 'Apartemen':
                return 'apartemen';

            case 'Tagihan / Piutang Dagang':
                return 'tagihan-piutang';

            case 'Tanah dan/atau Bangunan KPR - SEDERHANA':
                return 'tanah-bangunan-kpr-sederhana';

            default:
                return 'lainnya';
        }
    }

   public function checkBuildJson($input, $rows = [])
{
    $input = trim($input);

    // Pastikan rows selalu array
    if (!is_array($rows)) {
        $rows = [$rows];
    }

    switch ($input) {
        case 'Tanah dan Bangunan eks KPR-BPPN':
        case 'Pabrik':
        case 'Tanah dan/atau Bangunan':
        case 'Apartemen':
        case 'Tanah dan/atau Bangunan KPR - SEDERHANA':
            $assetJson = json_decode($this->checkAsset($rows)[0] ?? '', true);
            $tanahJson = json_decode(buildInspeksiTanah($rows)[0] ?? '', true);
            $bangunanJson = json_decode(buildInspeksiBangunan($rows)[0] ?? '', true);
            $lingkunganJson = json_decode($this->checkLingkungan($rows)[0] ?? '', true);

            $nomorLpj = $rows[0]['mig_nomor_lpj'] ?? null;
            $kesimpulanRows = $this->loadKesimpulanByNomorLpj($nomorLpj);


            $faktaJson = [];
            if (!empty($kesimpulanRows)) {
                $faktaResult = $this->checkKesimpulan($kesimpulanRows);
                $faktaJson = json_decode($faktaResult[0] ?? '', true)['fakta'] ?? [];
            }

            if($nomorLpj === '252845'){
                //dd($kesimpulanRows,$faktaResult, $faktaJson);
            }

            return json_encode([
                'asset' => $assetJson['asset'] ?? [],
                'tanah' => $tanahJson['tanah'] ?? [],
                'bangunan' => $bangunanJson['bangunan'] ?? [],
                'lingkungan' => $lingkunganJson['lingkungan'] ?? [],
                'fakta' => $faktaJson
            ], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);

        case 'Kapal Laut':
            $kapal = createInspeksiKapal($rows);
            return json_encode($kapal, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);

        case 'Kendaraan Bermotor':
            $kendaraan = createInspeksiKendaraan($rows);
            return json_encode($kendaraan, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);

        case 'Mesin-mesin dan Peralatan':
            $mesin = createInspeksiMesin($rows);
            return json_encode($mesin, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);

        case 'Pesawat Udara':
            $pesawat = createInspeksiPesawat($rows);
            return json_encode($pesawat, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);

        case 'Alat Berat':
            $alatBerat = createInspeksiAlatBerat($rows);
            return json_encode($alatBerat, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);

        case 'Barang Dagangan/FEO':
        case 'Deposito':
        case 'Rekening Giro / Tabungan':
        case 'Emas':
        case 'Jaminan Pribadi / Personal Guarantee':
        case 'Jaminan Perusahaan / Corporate Guarantee':
        case 'Resi Gudang':
        case 'Surat Berharga dan Saham':
        case 'Persediaan Barang / Barang Dagangan':
        case 'Tagihan / Piutang Dagang':
             return json_encode([
                'status' => 'pending',
                'message' => 'Fungsi untuk "' . $input . '" belum diimplementasikan.',
                'data' => $rows
            ]);
        case 'Tanah dan Bangunan (KerjaSama)':
        case 'Tanah Kavling (Kerjasama)':
            $pesawat = buildRapJsonData($rows);
            return json_encode($pesawat, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
        default:
            return json_encode([
                'status' => 'unknown',
                'message' => 'Jenis aset tidak dikenali: ' . $input,
                'data' => $rows
            ]);
        }
    }

    /**
     * Membangun JSON terstruktur yang dikelompokkan berdasarkan judul "mig_jenis_legalitas_jaminan_name".
     * Setiap item berisi pasangan label dan value sesuai kolom "name" dan nilai dari
     * "mig_name_keterangan_lain" (prioritas) atau "mig_name_keterangan" jika yang lain kosong.
     *
     * Contoh hasil:
     * {
     *   "STATUS KEPEMILIKAN, HUBUNGAN DAN PENGHUNI": [
     *     {"label": "Hubungan Penghuni Jaminan dengan Debitur", "value": "Kosong"},
     *     {"label": "Hubungan Pemilik Jaminan dengan Debitur", "value": "SHGB An Developer"}
     *   ],
     *   "ANALISA TANAH DAN BANGUNAN": [
     *     {"label": "Partisi", "value": "Batako"}
     *   ]
     * }
     *
     * Logging: Mencatat awal proses, jumlah kategori yang dibangun, dan panjang JSON hasil.
     *
     * @param array $rows Baris-baris CSV untuk satu nomor jaminan
     * @return string|null JSON terstruktur atau null bila tidak ada data
     */
    private function buildGroupedLegalitas(array $rows): ?string
    {
        Log::info('buildGroupedLegalitas: mulai membangun struktur JSON dari baris CSV', [
            'rows_count' => count($rows)
        ]);

        $grouped = [];

        foreach ($rows as $row) {
            $title = trim($row['mig_jenis_legalitas_jaminan_name'] ?? '');
            if ($title === '') {
                // Lewati baris tanpa judul kategori
                continue;
            }

            $label = trim($row['name'] ?? '');
            //$valueRaw = $row['mig_name_keterangan_lain'] ?? $row['mig_name_keterangan'] ?? null;

            $other = trim((string)($row['mig_name_keterangan_lain'] ?? ''));
            $val   = trim((string)($row['mig_name_keterangan'] ?? ''));

            $value = $other !== '' ? $val.', '.$other : $val;

            if (!array_key_exists($title, $grouped)) {
                $grouped[$title] = [];
            }

            // Simpan pasangan label-value sesuai spesifikasi
            $grouped[$title][] = [
                'label' => $label,
                'value' => $value
            ];
        }

        if (empty($grouped)) {
            Log::warning('buildGroupedLegalitas: tidak ada data terkelompok, mengembalikan null');
            return null;
        }

        $json = json_encode($grouped, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
        Log::info('buildGroupedLegalitas: selesai membangun JSON', [
            'categories' => count($grouped),
            'length' => strlen($json)
        ]);

        return $json;
    }

    function kv_to_json(string $input, string $pairSep = ';', string $kvSep = ':'): string {

            if($input === ''){
                return '';
            }

            // Pecah berdasarkan ';' dan bersihkan spasi
            $pairs = preg_split('/\s*' . preg_quote($pairSep, '/') . '\s*/u', trim($input), -1, PREG_SPLIT_NO_EMPTY);

            $result = [];
            $counts = [];

            foreach ($pairs as $pair) {
                // Bagi hanya pada pemisah ':' pertama agar nilai yang masih mengandung ':' tetap utuh
                $parts = preg_split('/\s*' . preg_quote($kvSep, '/') . '\s*/u', $pair, 2);
                if (count($parts) < 2) {
                    // jika format tidak valid, skip
                    continue;
                }

                [$rawKey, $rawVal] = $parts;

                // Normalisasi ringan: trim & rapikan spasi berlebih pada key
                $key = trim(preg_replace('/\s+/u', ' ', $rawKey));
                $val = trim($rawVal);

                // Tangani duplikasi key
                if (isset($counts[$key])) {
                    $counts[$key]++;
                    $useKey = $key . '_' . $counts[$key]; // Atas Nama_2, Atas Nama_3, ...
                } else {
                    $counts[$key] = 1;
                    $useKey = $key; // pertama kali pakai nama aslinya
                }

                $result[$useKey] = $val;
            }

            return json_encode($result, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT);
        }
}
