<?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;

class MigrationPembandingSeeder extends Seeder
{
    protected $errorLogFile = __DIR__ . '/csv/inspeksi/pembanding_20251016_error.csv';
    /**
     * Run the database seeds.
     */
    public function run()
    {
        // Path ke file csv
        $filePath = realpath(__DIR__ . '/csv/inspeksi/pembanding_20251016.csv');

        if (!$filePath) {
            Log::error('File csv tidak ditemukan: ' . __DIR__ . '/csv/inspeksi/pembanding_20251016.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 = 300;
        $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_lpj
        $groupedRows = $this->groupRowsByJaminan($rows);

        foreach ($groupedRows as $nomorLpj => $groupRows) {
            try {
                // Dapatkan info permohonan untuk update inspeksi
                $nomorRegis = $this->getNomorRegistrasiPermohonan($nomorLpj, $branchCache);
                if (!$nomorRegis) {
                    Log::warning("Nomor registrasi tidak ditemukan untuk nomor LPJ: {$nomorLpj}");
                    $errorCount++;
                    $errorDebitureIds[] = $nomorLpj;
                    continue;
                }

                // Bangun JSON data pembanding
                $pembandingJson = $this->checkPembanding($groupRows);

                // Update ke tabel inspeksi

                // print_r($pembandingJson);
                $inspeksi = Inspeksi::where('permohonan_id', $nomorRegis['id'])
                        ->where('dokument_id', $nomorRegis['dokument_id'])
                        ->update([
                            'data_pembanding' => $pembandingJson,
                            'updated_at' => now()
                        ]);

                $this->command->info("Berhasil update data_pembanding untuk nomor LPJ: {$nomorLpj}");

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

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

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

        if($row['mig_nomor_lpj']=='251936'){
            dd($grouped);
        }

        return $grouped;
    }

    private function checkPembanding(array $rows)
    {
        $pembandingList = [];

        foreach ($rows as $row) {
            // Pastikan kolom penting tersedia
            $urutan = (int)($row['mig_urutan'] ?? 999);
            $pembanding = trim($row['mig_pembanding'] ?? '');

            // CUKUP VALIDASI PEMBANDING SAJA
            if (empty($pembanding)) {
                continue;
            }

            $pembandingList[] = [
                'urutan' => $urutan,
                'keterangan' => $pembanding,
            ];
        }

        // Urutkan berdasarkan urutan
        usort($pembandingList, function ($a, $b) {
            return $a['urutan'] <=> $b['urutan'];
        });

        // Hapus indeks 'urutan'
        $finalPembanding = array_map(function ($item) {
            unset($item['urutan']);
            return $item;
        }, $pembandingList);

        return json_encode([
            'data_pembanding' => $finalPembanding
        ], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
    }
    private function getNomorRegistrasiPermohonan($nomor_jaminan_id, array &$cache)
    {
        if (isset($cache[$nomor_jaminan_id])) {
            return $cache[$nomor_jaminan_id];
        }

        $permohonan = Permohonan::where('nomor_lpj', $nomor_jaminan_id)->first();

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

        $dokumenJaminan = DokumenJaminan::where('permohonan_id', $permohonan->id)->first();

        $result = [
            'id' => $permohonan->id,
            'dokument_id' => $dokumenJaminan ? $dokumenJaminan->id : null
        ];

        $cache[$nomor_jaminan_id] = $result;

        return $result;
    }

    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]);

    }
}
