<?php
    declare(strict_types=1);

    use Illuminate\Support\Facades\Log;
    use Illuminate\Support\Facades\DB;

    use Carbon\Carbon;
    use Modules\Location\Models\City;
    use Modules\Location\Models\District;
    use Modules\Location\Models\Province;
    use Modules\Location\Models\Village;
    use Modules\Lpj\Models\CustomField;
    use Modules\Lpj\Models\HolidayCalendar;
    use Modules\Lpj\Models\JenisDokumen;
    use Modules\Lpj\Models\Laporan;
    use Modules\Lpj\Models\PenawaranDetailTender;
    use Modules\Lpj\Models\PenawaranTender;
    use Modules\Lpj\Models\Penilaian;
    use Modules\Lpj\Models\TeamsUsers;
    use Modules\Usermanagement\Models\User;
    use Illuminate\Support\Facades\File;
    use Illuminate\Support\Facades\Storage;

    /**
     * Format tanggal ke dalam format Bahasa Indonesia
     *
     * Mengubah tanggal menjadi format yang lebih mudah dibaca dalam Bahasa Indonesia.
     * Contoh: "15 Januari 2024" atau "15 Januari 2024 pukul 14.30 WIB"
     *
     * @param string|mixed $date Tanggal yang akan diformat (string tanggal atau null)
     * @param bool $time Apakah akan menampilkan waktu juga (default: false)
     * @return string Tanggal yang sudah diformat dalam Bahasa Indonesia
     *
     * @example
     * formatTanggalIndonesia('2024-01-15') // "15 Januari 2024"
     * formatTanggalIndonesia('2024-01-15 14:30:00', true) // "15 Januari 2024 pukul 14.30 WIB"
     * formatTanggalIndonesia(null) // ""
     * formatTanggalIndonesia('invalid-date') // "invalid-date" (return as-is jika error)
     */
    function formatTanggalIndonesia($date, $time = false): string
    {
        Log::debug('Memulai format tanggal Indonesia', [
            'date' => $date,
            'time' => $time
        ]);

        // Validasi input null atau kosong
        if (empty($date)) {
            Log::debug('Tanggal kosong, return empty string');
            return '';
        }

        Carbon::setLocale('id');

        try {
            $waktu = Carbon::parse($date);

            if (!$time) {
                $result = $waktu->translatedFormat('d F Y');
                Log::debug('Format tanggal berhasil', ['result' => $result]);
                return $result;
            }

            $result = $waktu->translatedFormat('d F Y') . ' pukul ' . $waktu->format('H.i') . ' WIB';
            Log::debug('Format tanggal dengan waktu berhasil', ['result' => $result]);
            return $result;

        } catch (Throwable $e) {
            Log::warning('Gagal parse tanggal', [
                'date' => $date,
                'error' => $e->getMessage()
            ]);
            // Return input as-is jika gagal parse
            return (string) $date;
        }
    }

    /**
     * Format angka ke dalam format mata uang Rupiah Indonesia
     *
     * Mengubah angka menjadi format mata uang Rupiah dengan pemisah ribuan
     * dan menggunakan koma sebagai pemisah desimal sesuai standar Indonesia.
     *
     * @param int|float|string $number Angka yang akan diformat (bisa negatif)
     * @param int $decimals Jumlah digit desimal (default: 0)
     * @return string Angka yang sudah diformat dalam format Rupiah
     *
     * @example
     * formatRupiah(1500000) // "Rp 1.500.000"
     * formatRupiah(1500000.50, 2) // "Rp 1.500.000,50"
     * formatRupiah(-500000) // "Rp -500.000"
     * formatRupiah(0) // "Rp 0"
     * formatRupiah(null) // "Rp 0"
     */
    function formatRupiah($number, $decimals = 0, $withSymbol = true): string
    {
        Log::debug('Memulai format Rupiah', [
            'number' => $number,
            'decimals' => $decimals,
            'withSymbol' => $withSymbol
        ]);

        // Handle null atau kosong
        if ($number === null || $number === '') {
            Log::debug('Number null atau kosong, return Rp 0');
            return $withSymbol ? 'Rp 0' : '0';
        }

        // Remove dots if present
        $number = str_replace('.', '', (string) $number);

        // Konversi ke float dan handle error
        try {
            $number = (float) $number;
        } catch (Throwable $e) {
            Log::warning('Gagal konversi number ke float', [
                'number' => $number,
                'error' => $e->getMessage()
            ]);
            return $withSymbol ? 'Rp 0' : '0';
        }

        // Validasi decimals
        $decimals = max(0, (int) $decimals);

        $formatted = number_format($number, $decimals, ',', '.');
        $result = $withSymbol ? 'Rp ' . $formatted : $formatted;
        Log::debug('Format Rupiah berhasil', ['result' => $result]);

        return $result;
    }

    function formatAlamat($alamat)
    {
        return ($alamat->address ? $alamat->address . ', ' : '') . (isset($alamat->village) ? $alamat->village->name . ', ' : '') . (isset($alamat->city) ? $alamat->city->name . ', ' : '') . (isset($alamat->province) ? $alamat->province->name . ', ' : '') . ($alamat->village->postal_code ?? '');
    }

    // andy add
    function checkActiveDateRangePenawaran($id)
    {
        $penawaran = PenawaranTender::find($id);

        $start_date  = strtotime($penawaran->start_date);
        $end_date    = strtotime($penawaran->end_date);
        $todays_date = strtotime(now());
        //$todays_date = strtotime("+1 day", strtotime(now()));

        $allow = true;
        if ($todays_date >= $start_date && $todays_date <= $end_date) {
            //Penawaran dibuka
            $allow = true;
        } else {
            if ($todays_date < $start_date) {
                //Penawaran Belum dibuka
                $allow = true;
            } else {
                //Penawaran sudah ditutup
                $allow = false;
            }
        }

        return $allow;
    }

    function checkKelengkapanDetailKJPP($id)
    {
        $allow = true;
        // DB::enableQueryLog();
        // detail_penawaran apakah isian biaya_penawaran, attachment, dokumen_persetujuan sudah lengkap?
        $query = PenawaranDetailTender::select('id')->where('penawaran_id', '=', $id)->where('status', '=', 1)->where(
            function ($query) {
                // no_proposal
                $query->orWhere('no_proposal', '', "");
                $query->orWhereNull('no_proposal');

                // tgl_proposal
                $query->orWhere('tgl_proposal', '', "");
                $query->orWhereNull('tgl_proposal');

                $query->orWhere('biaya_penawaran', '', "");
                $query->orWhereNull('biaya_penawaran');

                $query->orWhere('attachment', '', "");
                $query->orWhereNull('attachment');

                $query->orWhere('dokumen_persetujuan', '', "");
                $query->orWhereNull('dokumen_persetujuan');
            },
        )->get();

        if (sizeof($query) > 0) {
            $allow = false;
        }

        return $allow;
    }

    // convert
    function convertSlug($slug)
    {
        $words = explode('-', $slug);

        foreach ($words as $index => $word) {
            $words[$index] = strtoupper($word);
        }

        return implode(' ', $words);
    }

    // generate last penawaran.code
    function onLastnumberCodePenawaran()
    : string
    {
        // ambil code terakhir
        $maxCode = PenawaranTender::max('code');
        // chek data penawaran terakhir --> mengurutkan data berdasarkan kolom `created_at` secara DESC
        // $penawaran = PenawaranTender::latest()->first();
        $penawaran           = PenawaranTender::where('code', '=', $maxCode)->first();
        $code_penawaran_last = '';

        // nomor di set 0001
        $noUrutAkhirString = sprintf("%04s", 1);
        if ($penawaran) {
            $isNum = substr($maxCode, 2); // memastikan string ke 3 s/d 8 adalan numiric
            $isNP  = substr($maxCode, 0, 2);
            if ((8 == strlen($maxCode)) && ("NP" == $isNP) && (ctype_digit($isNum))) {
                $code_penawaran_last = substr($maxCode, -4);
                $year_penawaran_last = Carbon::parse($penawaran->created_at)->year;
                $year_now            = Carbon::now()->year;
                if ($year_now == $year_penawaran_last) {
                    $noUrutAkhirString = sprintf("%04s", abs($code_penawaran_last + 1));
                }
                // jika ternyata tahun tdk sama (kurang dari tahun sekarang), maka nomor di set 0001
            }

        }

        return 'NP' . Carbon::now()->format('y') . $noUrutAkhirString;
    }

    // generate last penawaran.no_spk
    function onLastnumberCodePenawaranSPK($jenis_laporan_code)
    : string
    {

        // 20241124_001 ==> spk_no_core
        // XXX / PJ / JKT / MONTH-ROM / FR|SR / 2024
        // 001 / PJ / JKT / XI / FR / 2024
        $maxCode               = PenawaranTender::max('spk_no_core');
        $penawaran             = PenawaranTender::where('spk_no_core', '=', $maxCode)->first();
        $no_spk_penawaran_last = '';
        $year_penawaran_last   = '';
        $year_now              = Carbon::now()->year;
        // nomor di set 001
        $noUrutAkhirString = sprintf("%03s", 1);
        if ($penawaran) {
            $no_spk_penawaran_last = substr($maxCode, -3);
            $year_penawaran_last   = substr($maxCode, 0, 4);

            if ($year_now == $year_penawaran_last) {
                $noUrutAkhirString = sprintf("%03s", abs($no_spk_penawaran_last + 1));
            }
            // jika ternyata tahun tdk sama (kurang dari tahun sekarang), maka nomor di set 001
        }

        $month = onRomawi(Carbon::now()->month);

        $lastSPK = $noUrutAkhirString . ' / PJ / JKT / ' . $month . ' / ' . $jenis_laporan_code . ' / ' . $year_now;
        return $lastSPK;
    }

    function onRomawi(int $bln)
    : string
    {
        return convertToRoman($bln);
    }

    function penyebut($nilai)
    {
        $nilai = abs($nilai);
        $huruf = [
            "",
            "satu",
            "dua",
            "tiga",
            "empat",
            "lima",
            "enam",
            "tujuh",
            "delapan",
            "sembilan",
            "sepuluh",
            "sebelas"
        ];
        $temp  = "";
        if ($nilai < 12) {
            $temp = " " . $huruf[$nilai];
        } else if ($nilai < 20) {
            $temp = penyebut($nilai - 10) . " belas";
        } else if ($nilai < 100) {
            $temp = penyebut($nilai / 10) . " puluh" . penyebut($nilai % 10);
        } else if ($nilai < 200) {
            $temp = " seratus" . penyebut($nilai - 100);
        } else if ($nilai < 1000) {
            $temp = penyebut($nilai / 100) . " ratus" . penyebut($nilai % 100);
        } else if ($nilai < 2000) {
            $temp = " seribu" . penyebut($nilai - 1000);
        } else if ($nilai < 1000000) {
            $temp = penyebut($nilai / 1000) . " ribu" . penyebut($nilai % 1000);
        } else if ($nilai < 1000000000) {
            $temp = penyebut($nilai / 1000000) . " juta" . penyebut($nilai % 1000000);
        } else if ($nilai < 1000000000000) {
            $temp = penyebut($nilai / 1000000000) . " milyar" . penyebut(fmod($nilai, 1000000000));
        } else if ($nilai < 1000000000000000) {
            $temp = penyebut($nilai / 1000000000000) . " trilyun" . penyebut(fmod($nilai, 1000000000000));
        }
        return $temp;
    }

    function terbilang($nilai)
    {
        if ($nilai < 0) {
            $hasil = "minus " . trim(penyebut($nilai));
        } else {
            $hasil = trim(penyebut($nilai));
        }
        return $hasil;
    }

    function hitungHariKerja($tanggalMulai, $tanggalSelesai)
    {
        $tanggalMulai   = Carbon::parse($tanggalMulai)->startOfDay();
        $tanggalSelesai = Carbon::parse($tanggalSelesai)->endOfDay();

        $hariKerja       = 0;
        $tanggalSekarang = $tanggalMulai->copy();

        while ($tanggalSekarang <= $tanggalSelesai) {
            // Cek apakah hari ini bukan Sabtu atau Minggu dan bukan hari libur
            if (!$tanggalSekarang->isWeekend() && !in_array($tanggalSekarang->format('Y-m-d'), holidays())) {
                $hariKerja++;
            }
            $tanggalSekarang->addDay();
        }

        return $hariKerja;
    }

    function countPermohonanForUser($userId)
    {
        $validStatuses = [
            'assign',
            'survey-completed',
            'proses-laporan',
            'paparan',
            'proses-paparan',
            'revisi-laporan',
            'revisi-paparan',
            'survey',
            'proses-survey',
            'request-reschedule',
            'reschedule',
            'rejected-reschedule',
            'approved-reschedule',
            'revisi-survey',
            'revisi-pembayaran'
        ];

        $result = Penilaian::whereHas('userPenilai', function ($query) use ($userId) {
            $query->where('user_id', $userId);
        })
                           ->whereHas('permohonan', function ($query) use ($validStatuses) {
                               $query->whereIn('status', $validStatuses);
                           })
                           ->get()
                           ->groupBy(function ($item) {
                               // Pastikan mengakses properti dari model yang valid
                               return $item->userPenilai->first()->user_id . '-' . $item->permohonan->id;
                           })
                           ->map(function ($group) {
                               return [
                                   'statuses' => $group->pluck('permohonan.status')->unique()->values()->all(),
                               ];
                           });

        return $result->count();
    }


    function getMaxFileSize($jenis)
    {
        $jenisDokumen = JenisDokumen::where('name', $jenis)->first();
        if (!$jenisDokumen) {
            return 2048;
        }
        //konversi ke KB (1 MB = 1024 KB)
        $maxSizeInKB = (int) $jenisDokumen->max_size * 1024;

        return $maxSizeInKB;
    }

    function getUser($userId)
    {
        return User::find($userId);
    }

    function generateLpjUniqueCode($randomLength = 6)
    {

        $year  = date('y');
        $month = str_pad(date('m'), 2, '0', STR_PAD_LEFT);
        $day   = str_pad(date('d'), 2, '0', STR_PAD_LEFT);

        // Generate random numbers
        //$randomNumber = str_pad(mt_rand(0, pow(10, $randomLength) - 1), $randomLength, '0', STR_PAD_LEFT);
	$randomNumber = sprintf('%0' . $randomLength . 'd', mt_rand(0, pow(10, $randomLength) - 1));

        // Concatenate components to create the custom code
        return $year . $month . $day . $randomNumber;
    }

    function checkRegionUserName($userId)
    {
        $region = TeamsUsers::where('user_id', $userId)->first();
        if ($region) {
            return $region->team->regions->name;
        } else {
            return null;
        }
    }

    function getNomorLaporan($permohonanId, $documentId, $type = 'nomor_laporan')
    {

        $laporan = Laporan::where([
            'permohonan_id'      => $permohonanId,
            'dokumen_jaminan_id' => $documentId,
        ])->first();

        if (!$laporan) {
            return $type == 'nomor_laporan' ? '-' : null;
        }

        return $type == 'nomor_laporan' ? $laporan->nomor_laporan : $laporan->created_at;
    }

    function getCustomField($param)
    {
        if (is_numeric($param)) {
            $field = CustomField::find($param);
        } else {
            $field = CustomField::where(['name' => $param])->first();
        }
        if ($field) {
            return $field;
        } else {
            return null;
        }
    }

    function getWilayahName($code, $type)
    {
        try {
            $wilayah = null;

            if (!$code) {
                return null;
            }

            switch ($type) {
                case 'province':
                    $wilayah = Province::where('code', $code)->first();
                    return $wilayah ? $wilayah->name : null;

                case 'city':
                    $wilayah = City::where('code', $code)->first();
                    return $wilayah ? $wilayah->name : null;

                case 'district':
                    $wilayah = District::where('code', $code)->first();
                    return $wilayah ? $wilayah->name : null;

                case 'village':
                    $wilayah = Village::where('code', $code)->first();
                    return $wilayah ? $wilayah->name : null;

                default:
                    return null;
            }
        } catch (Exception $e) {
            return null;
        }
    }


    function formatLabel($key)
    {

        static $labelCache = [];
        if (isset($labelCache[$key])) {
            return $labelCache[$key];
        }

        $customLabel      = CustomField::where('name', $key)->first();
        $labelCache[$key] = $customLabel->label ?? ucwords(str_replace('_', ' ', $key));

        return $labelCache[$key];
    }

    function calculateSLA($permohonan, $type)
    {
        if (!$type) {
            return null;
        }

        $nilai_plafond   = in_array($permohonan->nilai_plafond_id, [2, 3]);
        $nilai_plafond_2 = in_array($permohonan->nilai_plafond_id, [1]);

        $slaMap = [
            'resume'    => $nilai_plafond ? 2 : null,
            'paparan'   => $nilai_plafond ? 2 : null,
            'standard'  => $nilai_plafond ? 3 : null,
            'sederhana' => $nilai_plafond ? 2 : null,
            'paparan'   => $nilai_plafond_2 ? 3 : null,
            'rap'       => 3,
            'memo'      => $nilai_plafond ? 1 : null
        ];

        if ($type === 'paparan' && isset($permohonan->tujuanPenilaian->name) && $permohonan->tujuanPenilaian->name === 'rap') {
            return 2;
        }

        return $slaMap[$type] ?? null;
    }


    /**
     * Menghitung total nilai berdasarkan key dan jenis legalitas.
     *
     * @param array  $detailsArray
     * @param string $key
     * @param int    $jenisLegalitas
     *
     * @return int
     */
    function calculateTotalLuas($detailsArray, $key, $jenisLegalitas, $defaultJenisLegalitas, $fallbackJenisLegalitas)
    {
        $total = 0;

        if ($detailsArray) {
            foreach ($detailsArray as $item) {
                if (isset($item->jenis_legalitas_jaminan_id) && $item->jenis_legalitas_jaminan_id === $jenisLegalitas) {
                    $details = json_decode($item->details, true);

                    if (is_array($details)) {
                        foreach ($details as $detail) {
                            if (isset($detail[$key])) {
                                $total += (int) $detail[$key];
                            }
                        }
                    }
                }
            }

            // Jika total masih 0, gunakan jenis jaminan ppjb
            if ($total === 0) {
                foreach ($detailsArray as $item) {
                    if (isset($item->jenis_legalitas_jaminan_id) && $item->jenis_legalitas_jaminan_id === $defaultJenisLegalitas) {
                        $details = json_decode($item->details, true);

                        if (is_array($details)) {
                            foreach ($details as $detail) {
                                if (isset($detail[$key]) && $detail[$key] !== null) {
                                    $total += (int) $detail[$key];
                                }
                            }
                        }
                    }
                }
            }

            // jika total masih kosong juga maka gunakan ppb
            if ($total === 0 && $fallbackJenisLegalitas !== null) {
                foreach ($detailsArray as $item) {
                    if (isset($item->jenis_legalitas_jaminan_id) && $item->jenis_legalitas_jaminan_id === $fallbackJenisLegalitas) {
                        $details = json_decode($item->details, true);

                        if (is_array($details)) {
                            foreach ($details as $detail) {
                                if (isset($detail[$key]) && $detail[$key] !== null) {
                                    $total += (int) $detail[$key];
                                }
                            }
                        }
                    }
                }
            }
        }

        return $total > 0 ? $total : 0;
    }


    function ubahNomorHp($nomorHp)
    {

        $nomorHp = preg_replace('/\D/', '', $nomorHp);
        if (strpos($nomorHp, '62') === 0) {
            $nomorBaru = substr($nomorHp, 0, 5) . "xxxxx";
            return '+' . $nomorBaru;
        } else if (strpos($nomorHp, '0') === 0) {

            $nomorBaru = substr($nomorHp, 0, 5) . "xxxxxx";
            return $nomorBaru;
        } else {
            return "Nomor HP tidak valid";
        }
    }

    function parsePembandingMigration($keterangan) {
        $keterangan = preg_replace('/[-]{5,}/', '',$keterangan);   // Hapus ------
        $keterangan = preg_replace('/[.]{5,}/', '',$keterangan);   // Hapus .....

        $keterangan = preg_replace('/\s+/', ' ',$keterangan);
        $keterangan = preg_replace('/\s*\n\s*/', "\n",$keterangan);

        // Pecah teks per baris untuk diproses
        $lines = explode("\n",$keterangan);
        $cleaned = [];

        foreach ($lines as $line) {
            $line = trim($line);
            if (!empty($line)) {
                // Format angka dalam format Rp. 123.456.789
                $line = preg_replace_callback('/Rp\.\s*([\d.,]+)/', function($matches) {
                    $angka = str_replace(['.', ','], '', $matches[1]);
                    return 'Rp. ' . number_format((int)$angka, 0, ',', '.');
                }, $line);

                // Jika ada tanda pagar (#), pisahkan menjadi baris baru
                $line = str_replace('#', "\n#", $line);

                $cleaned[] = $line;
            }
        }

        return implode("\n", $cleaned);
    }

    /**
     * get full path to internal storage file or external storage file
     *
     * @param string $path
     * @return string
     */

    function getFilePath($path)
    {
        // define base path external storage (use .env) example: 'F:\path\to\storage' in windows
        $externalBase = env('EXTERNAL_STORAGE_BASE_PATH', 'F:LPJ/lpj/LPJ Gambar/001/');

        $segments = explode('/', $path);

        if(strtoupper($segments[0]) === 'SURVEYOR'){
            $year = $segments[1];
            $month = ucfirst(strtolower($segments[2]));
            $date = $segments[3];
            $code = $segments[4];
            $file = $segments[5] ?? '';

            $extenalFullpath = $externalBase . $year . '/' . $month . '/' . $date . '/' . $code . '/' . $file;

            if(File::exists($extenalFullpath)){
                return $extenalFullpath;
            }
        }

        // if not found in external storage, try to find in internal storage
        if (Storage::exists($path)) {
            return Storage::url('app/' . $path);
        }
        return $path;
    }


    function parseTimestamp(?string $timestamp): ?string
    {
        if (!$timestamp) {
            return null;
        }

        // Trim whitespace dan normalize
        $timestamp = trim($timestamp);

        // Log untuk debugging
        Log::info('Mencoba parsing timestamp: "' . $timestamp . '"');

        // Parsing dengan DateTime native PHP untuk lebih robust
        try {
            // Pattern untuk format d/m/Y H:i:s
            if (preg_match('/^(\d{1,2})\/(\d{1,2})\/(\d{4})\s+(\d{1,2}):(\d{1,2}):(\d{1,2})$/', $timestamp, $matches)) {
                $day = (int) $matches[1];
                $month = (int) $matches[2];
                $year = (int) $matches[3];
                $hour = (int) $matches[4];
                $minute = (int) $matches[5];
                $second = (int) $matches[6];

                // Validasi nilai
                if ($day >= 1 && $day <= 31 && $month >= 1 && $month <= 12 && $year >= 1900 && $year <= 2100 &&
                    $hour >= 0 && $hour <= 23 && $minute >= 0 && $minute <= 59 && $second >= 0 && $second <= 59) {

                    // Buat DateTime object langsung
                    $dateTime = new \DateTime();
                    $dateTime->setDate($year, $month, $day);
                    $dateTime->setTime($hour, $minute, $second);

                    $result = $dateTime->format('Y-m-d H:i:s');
                    Log::info('Berhasil parsing dengan DateTime: ' . $timestamp . ' -> ' . $result);
                    return $result;
                }
            }

            // Pattern untuk format d/m/Y tanpa waktu
            if (preg_match('/^(\d{1,2})\/(\d{1,2})\/(\d{4})$/', $timestamp, $matches)) {
                $day = (int) $matches[1];
                $month = (int) $matches[2];
                $year = (int) $matches[3];

                // Validasi nilai
                if ($day >= 1 && $day <= 31 && $month >= 1 && $month <= 12 && $year >= 1900 && $year <= 2100) {

                    // Buat DateTime object langsung
                    $dateTime = new \DateTime();
                    $dateTime->setDate($year, $month, $day);
                    $dateTime->setTime(0, 0, 0);

                    $result = $dateTime->format('Y-m-d H:i:s');
                    Log::info('Berhasil parsing tanpa waktu dengan DateTime: ' . $timestamp . ' -> ' . $result);
                    return $result;
                }
            }
        } catch (\Exception $e) {
            Log::error('Gagal parsing dengan DateTime: ' . $timestamp . '. Error: ' . $e->getMessage());
        }

        // Fallback ke format Carbon standar untuk format lainnya
        $formats = [
            'Y-m-d H:i:s',
            'Y-m-d',
            'd-m-Y H:i:s',
            'd-m-Y',
            'j-n-Y H:i:s',
            'j-n-Y',
        ];

        foreach ($formats as $format) {
            try {
                $carbon = \Carbon\Carbon::createFromFormat($format, $timestamp);

                if ($carbon && $carbon->format($format) === $timestamp) {
                    // Jika format tidak mengandung waktu, set ke awal hari
                    if (!str_contains($format, 'H:i:s')) {
                        $carbon = $carbon->startOfDay();
                    }
                    Log::info('Berhasil parsing dengan format ' . $format . ': ' . $timestamp . ' -> ' . $carbon->toDateTimeString());
                    return $carbon->toDateTimeString();
                }
            } catch (\Exception $e) {
                // Lanjut ke format berikutnya
                continue;
            }
        }

        Log::error('Tidak dapat memparsing timestamp dengan format apapun: "' . $timestamp . '"');
        return null;
    }
