<?php

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

function formatTanggalIndonesia($date, $time = false)
{
    Carbon::setLocale('id');
    try {
        $waktu = Carbon::parse($date);
        if (!$time) {
            return $waktu->translatedFormat('d F Y');
        }
        return $waktu->translatedFormat('d F Y') . ' pukul ' . $waktu->format('H.i') . ' WIB';
    } catch (\Throwable $e) {
        return $date;
    }
    
}


function formatRupiah($number)
{
    $number = (float) $number;
    return 'Rp ' . number_format($number, 0, ',', '.');
}


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->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();
    // $sql = DB::getQueryLog();


    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) && (isNumeric($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;
}

function isNumeric($str)
{
    return ctype_digit($str);
}

// 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
{
    switch ($bln) {
        case 1:
            return "I";
            break;
        case 2:
            return "II";
            break;
        case 3:
            return "III";
            break;
        case 4:
            return "IV";
            break;
        case 5:
            return "V";
            break;
        case 6:
            return "VI";
            break;
        case 7:
            return "VII";
            break;
        case 8:
            return "VIII";
            break;
        case 9:
            return "IX";
            break;
        case 10:
            return "X";
            break;
        case 11:
            return "XI";
            break;
        case 12:
            return "XII";
            break;

    }

}

function penyebut($nilai)
{
    $nilai = abs($nilai);
    $huruf = array("", "satu", "dua", "tiga", "empat", "lima", "enam", "tujuh", "delapan", "sembilan", "sepuluh", "sebelas");
    $temp = "";
    if ($nilai < 12) {
        $temp = " ". $huruf[$nilai];
    } elseif ($nilai < 20) {
        $temp = penyebut($nilai - 10). " belas";
    } elseif ($nilai < 100) {
        $temp = penyebut($nilai / 10)." puluh". penyebut($nilai % 10);
    } elseif ($nilai < 200) {
        $temp = " seratus" . penyebut($nilai - 100);
    } elseif ($nilai < 1000) {
        $temp = penyebut($nilai / 100) . " ratus" . penyebut($nilai % 100);
    } elseif ($nilai < 2000) {
        $temp = " seribu" . penyebut($nilai - 1000);
    } elseif ($nilai < 1000000) {
        $temp = penyebut($nilai / 1000) . " ribu" . penyebut($nilai % 1000);
    } elseif ($nilai < 1000000000) {
        $temp = penyebut($nilai / 1000000) . " juta" . penyebut($nilai % 1000000);
    } elseif ($nilai < 1000000000000) {
        $temp = penyebut($nilai / 1000000000) . " milyar" . penyebut(fmod($nilai, 1000000000));
    } elseif ($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;
}
// andy add


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 holidays()
{
    return HolidayCalendar::pluck('date')->map(
        function ($item) {
            return Carbon::parse($item)->format('Y-m-d');
        },
    )->toArray();
}

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

    // 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;
    } elseif (strpos($nomorHp, '0') === 0) {

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