<?php

namespace Modules\Lpj\Http\Controllers;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Maatwebsite\Excel\Facades\Excel;
use Modules\Lpj\Exports\BasicDataSurveyorExport;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Log;
use Barryvdh\DomPDF\Facade\Pdf;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Carbon;
use Exception;
use Modules\Lpj\Models\Debiture;
use Modules\Lpj\Models\LaporanExternal;
use Modules\Lpj\Models\Permohonan;
use Modules\Lpj\Models\Branch;
use Modules\Lpj\Models\BentukTanah;
use Modules\Lpj\Models\KonturTanah;
use Modules\Location\Models\Province;
use Modules\Location\Models\City;
use Modules\Location\Models\District;
use Modules\Location\Models\Village;
use Modules\Lpj\Models\PosisiKavling;
use Modules\Lpj\Models\KondisiFisikTanah;
use Modules\Lpj\Models\FotoObjekJaminan;
use Modules\Lpj\Models\Perizinan;
use Modules\Lpj\Models\KetinggianTanah;
use Modules\Lpj\Models\SifatBangunan;
use Modules\Lpj\Models\JenisJaminan;
use Modules\Lpj\Models\JenisBangunan;
use Modules\Lpj\Models\KondisiBangunan;
use Modules\Lpj\Models\SpekBangunan;
use Modules\Lpj\Models\SpekKategoritBangunan;
use Modules\Lpj\Models\SaranaPelengkap;
use Modules\Lpj\Models\ArahMataAngin;
use Modules\Lpj\Models\Penilaian;
use Modules\Lpj\Models\PerkerasanJalan;
use Modules\Lpj\Models\Teams;
use Modules\Lpj\Models\Lantai;
use Modules\Lpj\Models\Inspeksi;
use Modules\Lpj\Models\ViewUnit;
use Modules\Lpj\Models\JenisUnit;
use Modules\Lpj\Models\BentukUnit;
use Modules\Lpj\Models\PosisiUnit;
use Modules\Lpj\Models\TerletakArea;
use Modules\Lpj\Models\FasilitasObjek;
use Modules\Lpj\Models\MerupakanDaerah;
use Modules\Lpj\Models\ModelAlatBerat;
use Modules\Lpj\Models\JenisPesawat;
use Modules\Lpj\Models\DokumenJaminan;
use Modules\Lpj\Models\DetailDokumenJaminan;
use Modules\Lpj\Models\JenisKapal;
use Modules\Lpj\Models\JenisKendaraan;
use Modules\Lpj\Models\HubunganPemilikJaminan;
use Modules\Lpj\Models\HubunganPenghuniJaminan;
use Modules\Lpj\Models\GolonganMasySekitar;
use Modules\Lpj\Models\TingkatKeramaian;
use Modules\Lpj\Models\TujuanPenilaian;
use Modules\Lpj\Models\LaluLintasLokasi;
use Modules\Lpj\Http\Requests\SurveyorRequest;
use Modules\Lpj\Jobs\SendJadwalKunjunganEmailJob;
use Modules\Lpj\Models\Authorization;
use Modules\Lpj\Services\SurveyorValidateService;
use Modules\Lpj\Services\SaveFormInspesksiService;
use Modules\Lpj\Models\PermohonanHistory;

class SurveyorController extends Controller
{
    public $user;
    public $validateService;
    public $inspeksiService;

    public function __construct(SurveyorValidateService $validateService, SaveFormInspesksiService $inspeksiService)
    {
        $this->validateService = $validateService;
        $this->inspeksiService = $inspeksiService;
    }

    public function index()
    {
        return view('lpj::surveyor.index');
    }

    /**
     * Show the specified resource.
     */
    public function show($id)
    {
        $permohonan = Permohonan::with([
            'user',
            'debiture.province',
            'debiture.city',
            'debiture.district',
            'debiture.village',
            'branch',
            'tujuanPenilaian',
            'penilaian',
            'documents.jenisJaminan',
            'documents',
        ])->findOrFail($id);

        $surveyor = $id;
        $branches = Branch::all();
        $provinces = Province::all();
        $bentukTanah = BentukTanah::all();

        // Jalankan cleanup inspeksi otomatis untuk permohonan ini
        $this->cleanupInspeksiData($id);

        // Get all inspeksi data for this permohonan
        if (strtolower($permohonan->tujuanPenilaian->name) == 'rap') {
            $inspeksiData = Inspeksi::where('permohonan_id', $id)
            ->get()
            ->keyBy('dokument_id')
            ->map(function ($item) {
                return [
                    'data_form' => json_decode($item->data_form, true),
                    'foto_form' => json_decode($item->foto_form, true)
                ];
            });
        } else {
            $inspeksiData = Inspeksi::where('permohonan_id', $id)
            ->get()
            ->keyBy('dokument_id')
            ->map(function ($item) {
                return [
                    'data_form' => json_decode($item->data_form, true),
                    'foto_form' => json_decode($item->foto_form, true),
                    'denah_form' => json_decode($item->denah_form, true),
                    'data_pembanding' => json_decode($item->data_pembanding, true),
                ];
            });
        }

        $catatan_revisi_survey = PermohonanHistory::where('permohonan_id', $id)
           ->where('status', 'revisi-survey')->latest()->first();

        return view('lpj::surveyor.detail', compact(
            'permohonan',
            'surveyor',
            'branches',
            'provinces',
            'bentukTanah',
            'inspeksiData',
            'catatan_revisi_survey',
        ));
    }

    /**
     * Store form inspeksi.
     */
    public function store(Request $request)
    {
        $validatedData = $request->all();

        $fotoTypes = [
            'foto_gistaru',
            'foto_bhumi',
            'foto_argis_region',
            'foto_tempat',
            'foto_sentuh_tanahku',
            'upload_gs'
        ];

        // Hapus data foto dari $validatedData
        foreach ($fotoTypes as $fotoType) {
            if (isset($validatedData[$fotoType])) {
                unset($validatedData[$fotoType]);
            }
        }

        $result = $this->inspeksiService->storeInspeksi($validatedData, $request->input('type'), $request);

        if ($result['success']) {
            return response()->json($result, 200);
        }
        return response()->json($result, 500);
    }

    public function storeDenah(Request $request)
    {
        $validator = $request->validate([
            'foto_denah.*' => 'nullable|file|mimes:jpg,jpeg,png,bmp,gif,webp,pdf',
            'nama_denah.*' => 'nullable|string|max:255',
            'luas_denah.*' => 'nullable',
            'permohonan_id' => 'required|exists:permohonan,id',
            'dokument_id' => 'required',
            'nomor_registrasi' => 'required'
        ]);
        if ($validator) {
            try {

                $denahs = [];

                $inspeksi = Inspeksi::where('permohonan_id', $request->permohonan_id)
                    ->where('dokument_id', $request->dokument_id)
                    ->first();

                $existingDenah = $inspeksi ? json_decode($inspeksi->denah_form ?? '[]', true) : [];
                $existingDenahs = $existingDenah['denahs'] ?? [];

                if ($request->has('nama_denah')) {
                    foreach ($request->nama_denah as $index => $namaDenah) {
                        $denahItem = [
                            'nama_denah' => $namaDenah,
                            'luas_denah' => $request->luas_denah[$index] ?? null
                        ];

                        if ($request->hasFile('foto_denah') && isset($request->file('foto_denah')[$index])) {
                            $file = $request->file('foto_denah')[$index];
                            $denahItem['foto_denah'] = $this->uploadFile($file, 'foto_denah');
                        } elseif (isset($existingDenahs[$index]['foto_denah'])) {
                            $denahItem['foto_denah'] = $existingDenahs[$index]['foto_denah'];
                        }

                        $denahs[] = $denahItem;
                    }
                }

                if (empty($denahs) && !empty($existingDenahs)) {
                    $denahs = $existingDenahs;
                }

                $inspeksi = Inspeksi::firstOrNew([
                    'permohonan_id' => $request->permohonan_id,
                    'dokument_id' => $request->dokument_id
                ]);

                // Update denah_form
                $updatedDenah = ['denahs' => $denahs];
                $inspeksi->denah_form = json_encode($updatedDenah);
                $inspeksi->save();

                return response()->json([
                    'success' => true,
                    'message' => 'Data berhasil disimpan',
                    'data' => $updatedDenah
                ], 200);

            } catch (\Exception $e) {
                Log::error('Denah Store Error: ' . $e->getMessage());
                return response()->json([
                    'success' => false,
                    'message' => 'Gagal menyimpan data: ' . $e->getMessage()
                ], 500);
            }
        }
    }

    public function storeFoto(Request $request)
    {
        $validatedData = $this->validateFotoRequest($request);
        try {
            $inspeksi = Inspeksi::firstOrNew([
                'permohonan_id' => $request->input('permohonan_id'),
                'dokument_id' => $request->input('dokument_id')
            ]);
            // Get existing foto_form data if it exists
            $existingData = $inspeksi->exists && $inspeksi->foto_form
                ? json_decode($inspeksi->foto_form, true)
                : [];



            if (!$this->isValidFormat($existingData)) {
                $existingData = [];
            }

            // Upload berbagai jenis foto
            $newFoto = $this->handleFileUpload($request, 'upload_foto', $existingData);

            if (!empty($newFoto)) {
                $inspeksi->foto_form = json_encode($existingData);
                $inspeksi->save();

                return response()->json([
                    'success' => true,
                    'message' => 'Data berhasil disimpan',
                    'path' => $newFoto[0]['path'],
                ], 200);
            }

            return response()->json([
                'success' => false,
                'message' => 'Tidak ada data untuk disimpan'
            ], 400);
        } catch (Exception $e) {
            return response()->json(['success' => false, 'message' => 'Failed to upload: ' . $e->getMessage()], 500);
        }
    }

    /**
 * Validasi apakah format JSON sesuai dengan yang diinginkan.
 *
 * @param array $data
 * @return bool
 */
    private function isValidFormat($data)
    {
        if (!isset($data['upload_foto']) || !is_array($data['upload_foto'])) {
            return false;
        }

        return true;
    }


    public function updateFoto(Request $request)
    {
        try {
            // Validasi input
            $validated = $request->validate([
                'permohonan_id' => 'required',
                'dokument_id' => 'required|string',
                'name' => 'required|string|max:255',
                'description' => 'nullable|string',
                'category' => 'required|string|max:255',
                'sub' => 'nullable|string|max:255',
                'path' => 'nullable|string',
            ]);

            $inspeksi = Inspeksi::firstOrNew([
                'permohonan_id' => $validated['permohonan_id'],
                'dokument_id' => $validated['dokument_id'],
            ]);

            $cleanRequestPath = str_replace('/storage/', '', $validated['path']);

            $fotoForm = json_decode($inspeksi->foto_form, true) ?? [];


            if (!isset($fotoForm['upload_foto'])) {
                $fotoForm['upload_foto'] = [];
            }


            $existingIndex = null;
            if (!empty($validated['path'])) {
                foreach ($fotoForm['upload_foto'] as $index => $foto) {
                    if ($foto['path'] === $cleanRequestPath) {
                        $existingIndex = $index;
                        break;
                    }
                }
            }

            // Siapkan data baru
            $newFotoData = [
                'name' => $validated['name'],
                'description' => $validated['description'],
                'category' => $validated['category'],
                'sub' => $validated['sub'],
                'path' => $cleanRequestPath,
                'created_by' => Auth::user()->name,
                'created_at' => now()->toDateTimeString(),
                'updated_by' => Auth::user()->name,
                'updated_at' => now()->toDateTimeString(),
            ];

            if ($existingIndex !== null) {
                $existingFoto = $fotoForm['upload_foto'][$existingIndex];
                $fotoForm['upload_foto'][$existingIndex] = [
                    'name' => $validated['name'],
                    'description' => $validated['description'],
                    'category' => $validated['category'],
                    'sub' => $validated['sub'],
                    'path' => $cleanRequestPath,
                    'created_by' => $existingFoto['created_by'] ?? Auth::user()->name,
                    'created_at' => $existingFoto['created_at'] ?? now()->toDateTimeString(),
                    'updated_by' => Auth::user()->name,
                    'updated_at' => now()->toDateTimeString(),
                ];
            } else {
                $fotoForm['upload_foto'][] = $newFotoData;
            }

            // Simpan kembali data ke database
            $inspeksi->foto_form = json_encode($fotoForm);
            $inspeksi->save();

            return response()->json([
                'success' => true,
                'message' => 'Data berhasil diperbarui.',
            ], 200);

        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Gagal memperbarui data: ' . $e->getMessage(),
            ], 500);
        }
    }


    private function handleFileUpload(Request $request, $paramName, &$formatFotojson)
    {
        if ($request->hasFile($paramName)) {
            $files = $request->file($paramName);

            if (!is_array($files)) {
                $files = [$files];
            }

            $formatFotoData = [];
            $nomor_registrasi = $request->nomor_registrasi;


            $batchTimestamp = time();

            $existingFilePaths = [];
            if (isset($formatFotojson[$paramName]) && is_array($formatFotojson[$paramName])) {
                foreach ($formatFotojson[$paramName] as $existingFile) {
                    if (isset($existingFile['path'])) {
                        $existingFilePaths[] = $existingFile['path'];
                    }
                }
            }

            foreach ($files as $index => $file) {
                $originalName = $file->getClientOriginalName();
                $extension = $file->getClientOriginalExtension();
                $fileNameWithoutExt = pathinfo($originalName, PATHINFO_FILENAME);

                if (empty($fileNameWithoutExt)) {
                    $fileNameWithoutExt = "file_{$batchTimestamp}_{$index}";
                }

                $safeFileName = preg_replace('/[^a-zA-Z0-9_-]/', '_', $fileNameWithoutExt);
                $uniqueFileName = "{$batchTimestamp}_{$index}_{$safeFileName}.{$extension}";
                $path = "surveyor/{$paramName}/{$nomor_registrasi}/{$uniqueFileName}";

                if (in_array($path, $existingFilePaths)) {
                    $counter = 1;
                    do {
                        $uniquePath = "surveyor/{$paramName}/{$nomor_registrasi}/{$batchTimestamp}_{$index}_{$safeFileName}_{$counter}.{$extension}";
                        $counter++;
                    } while (in_array($uniquePath, $existingFilePaths));

                    $path = $uniquePath;
                }

                $savedPath = $file->storeAs('', $path, 'public');

                $existingFilePaths[] = $path;

                // Add file data
                $fotoData = [
                    'name' => $fileNameWithoutExt,
                    'path' => $savedPath,
                    'category' => 'lainnya',
                    'sub' => null,
                    'description' => null,
                    'created_by' => Auth::user()->name,
                    'created_at' => now()->toDateTimeString(),
                ];

                $formatFotoData[] = $fotoData;
            }

            // Only update if we have new photos to add
            if (!empty($formatFotoData)) {
                // Struktur JSON yang konsisten
                if (!isset($formatFotojson[$paramName])) {
                    $formatFotojson[$paramName] = $formatFotoData;
                } else {
                    $formatFotojson[$paramName] = array_merge(
                        $formatFotojson[$paramName] ?? [],
                        $formatFotoData
                    );
                }

                return $formatFotoData;
            }
        }

        return [];
    }



    public function hapusFoto(Request $request)
    {
        try {
            $permohonanId = $request->permohonan_id;
            $dokumentId = $request->dokument_id;
            $paramName = $request->param_name;

            $cleanRequestPath = str_replace('/storage/', '', $request->path);

            $inspeksi = Inspeksi::firstOrNew(
                ['permohonan_id' => $permohonanId, 'dokument_id' => $dokumentId]
            );
            $fotoForm = json_decode($inspeksi->foto_form, true);

            if (isset($fotoForm[$paramName]) && is_array($fotoForm[$paramName])) {
                // Filter foto yang tidak sesuai dengan path yang akan dihapus
                $fotoForm[$paramName] = array_values(array_filter(
                    $fotoForm[$paramName],
                    function ($foto) use ($cleanRequestPath) {
                        if ($foto['path'] === $cleanRequestPath) {
                            // Hapus file dari storage
                            \Storage::disk('public')->delete($cleanRequestPath);
                            return false;
                        }
                        return true;
                    }
                ));

                // Simpan kembali data ke database
                $inspeksi->foto_form = json_encode($fotoForm);
                $inspeksi->save();

                return response()->json([
                    'success' => true,
                    'message' => 'Foto berhasil dihapus',
                ], 200);
            }

            // Jika parameter tidak ditemukan
            return response()->json([
                'success' => false,
                'message' => 'Foto atau parameter tidak ditemukan',
            ], 400);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => $e->getMessage()
            ], 500);
        }
    }

    // Metode untuk mendapatkan foto yang sudah diupload
    public function getFoto(Request $request)
    {
        $permohonanId = $request->permohonan_id;
        $dokumentId = $request->dokument_id;
        $paramName = $request->param_name;

        $inspeksi = Inspeksi::firstOrNew(
            ['permohonan_id' => $permohonanId, 'dokument_id' => $dokumentId]
        );

        // Decode foto_form
        $fotoForm = json_decode($inspeksi->foto_form, true) ?? [];

        // Cari foto berdasarkan param name
        $fotos = $this->findFotoByParamName($fotoForm, $paramName);


        $data = array_map(function ($foto) {
            return [
                'name' => $foto['name'] ?? 'Foto',
                'path' => \Storage::url($foto['path'] ?? ''),
                'category' => $foto['category'] ?? 'lainnya',
                'sub' => $foto['sub'] ?? null,
                'description' => $foto['description'] ?? null,
                'upload_by' => $foto['upload_by'] ?? null,
            ];
        }, $fotos);

        return response()->json([
            'fotos' => $data,
            'success' => !empty($data),
        ]);
    }


    public function saveEditedImage(Request $request)
    {
        try {

            $request->validate([
                'edited_image' => 'required|string',
                'original_path' => 'required|string',
                'nomor_registrasi' => 'required',
            ]);

            // Decode base64 image
            $base64Image = $request->input('edited_image');
            if (str_contains($base64Image, ';base64,')) {
                [$metadata, $base64Image] = explode(';base64,', $base64Image);
            }

            $decodedImage = base64_decode($base64Image);
            if (!$decodedImage) {
                return response()->json([
                    'status' => 'error',
                    'message' => 'Gambar tidak valid',
                ], 400);
            }

            // Path asli
            $originalPath = $request->input('original_path');
            $fileName = basename($originalPath);
            $newFilePath = 'surveyor/upload_foto/'. $request->input('nomor_registrasi') . '/'  . $fileName;

            // Simpan file ke storage
            Storage::disk('public')->put($newFilePath, $decodedImage);

            return response()->json([
                'status' => 'success',
                'message' => 'Gambar berhasil disimpan',
                'file_path' => $newFilePath,
            ], 200);
        } catch (\Exception $e) {
            return response()->json([
                'status' => 'error',
                'message' => 'Terjadi kesalahan: ' . $e->getMessage(),
            ], 500);
        }
    }

    private function findFotoByParamName($fotoForm, $paramName)
    {
        // Mapping parameter name ke struktur JSON
        if (isset($fotoForm[$paramName]) && is_array($fotoForm[$paramName])) {
            return $fotoForm[$paramName]; // Kembalikan array foto jika ditemukan
        }

        // Jika parameter tidak ditemukan atau bukan array, kembalikan array kosong
        return [];
    }


    private function processObjekJaminanPhotos(Request $request, array $existingPhotos = [])
    {
        $photoField = 'foto_objek';
        $nameField = 'name_objek';
        $descriptionField = 'deskripsi_objek';

        // Mulai dengan data lama
        $result = $existingPhotos;

        if ($request->hasFile($photoField)) {
            $newFiles = $request->file($photoField, []);
            $newNames = $request->input($nameField, []);
            $newDescriptions = $request->input($descriptionField, []);

            foreach ($newFiles as $key => $file) {
                // Cari atau buat entri berdasarkan nama objek
                $existingIndex = $this->findObjekJaminanIndexByName($result, $newNames[$key]);

                // Buat entri baru untuk file yang diunggah
                $newPhotoEntry = [
                    $nameField => $newNames[$key],
                    $photoField => $this->uploadFile($file, $photoField . '.' . $key),
                    $descriptionField => $newDescriptions[$key] ?? '',
                ];

                // Jika sudah ada, update; jika belum, tambahkan
                if ($existingIndex !== false) {
                    // Hapus file lama jika ada
                    if (isset($result[$existingIndex][$photoField])) {
                        $this->deleteOfFile($result[$existingIndex][$photoField]);
                    }
                    $result[$existingIndex] = $newPhotoEntry;
                } else {
                    $result[] = $newPhotoEntry;
                }
            }
        }

        // Pastikan array tetap terurut dengan benar
        return array_values($result);
    }

    /**
     * Cari index objek jaminan berdasarkan nama objek
     */
    private function findObjekJaminanIndexByName(array $existingPhotos, string $name)
    {
        foreach ($existingPhotos as $index => $photo) {
            if (isset($photo['name_objek']) && $photo['name_objek'] === $name) {
                return $index;
            }
        }
        return false;
    }


    private function generateUniqueFileName($file, $prefix = '')
    {
        $extension = $file->getClientOriginalExtension();
        return $prefix . '_' . uniqid() . '.' . $extension;
    }

    private function deleteOfFile($filePath)
    {
        if ($filePath && Storage::exists($filePath)) {
            Storage::delete($filePath);
        }
    }

    /**
     * Custom validation request for foto
     */
    public function validateFotoRequest(Request $request)
    {
        $maxSize = getMaxFileSize('Foto');
        return $request->validate([
            'permohonan_id' => 'required',
            'dokument_id' => 'required',
            'nomor_registrasi' => 'required',
            'upload_foto.*' => 'required|image|mimes:jpeg,png,jpg,gif,svg,webp,bmp,tiff,heic,heif|max:'. $maxSize,
        ]);
    }

    public function submitSurveyor($id)
    {
        try {
            // Get button status check result
            $buttonStatusCheck = $this->checkButtonStatus($id);
            $buttonStatus = json_decode($buttonStatusCheck->getContent(), true);


            // Check if button should be disabled
            if ($buttonStatus['buttonDisable']) {
                return response()->json([
                    'success' => false,
                    'message' => 'Form belum lengkap. Pastikan semua data telah diisi dengan benar.',
                ], 422);
            }

            $inspeksiRecords = Inspeksi::with(['dokument.jenisJaminan'])
            ->where('permohonan_id', $id)
            ->get();


            $validateConfig = [
                'tanah' => 'validateTanah',
                'bangunan' => 'validateBangunan',
                'lingkungan' => 'validateLingkungan',
                'fakta' => 'validateFactData',
                'rap' => 'validateRapData',
                'apartemen-kantor' => 'validateUnitData',
            ];

            // Ambil data inspeksi
            $inspeksiRecords = Inspeksi::with(['dokument.jenisJaminan'])
                ->where('permohonan_id', $id)
                ->get();

            foreach ($inspeksiRecords as $inspeksi) {
                $cekname = $inspeksi->name;

                // Pecah nama menjadi array
                $names = array_map('trim', explode(',', $cekname));
                $dataForm = json_decode($inspeksi->data_form, true);

                foreach ($names as $name) {
                    // Validasi hanya untuk nama yang ada dalam konfigurasi
                    if (array_key_exists($name, $validateConfig)) {
                        $validateMethod = $validateConfig[$name];
                        $invalidFields = $this->validateService->{$validateMethod}($dataForm);

                        // Jika validasi gagal, kembalikan respons error
                        if ($invalidFields) {
                            return response()->json([
                                'success' => false,
                                'message' => ucfirst($name) . ' tidak valid: ' . implode(', ', $invalidFields),
                            ], 422);
                        }
                    }
                }
            }

            // If validation passes, update permohonan status
            $permohonan = Permohonan::with('jenisPenilaian')->findOrFail($id);

            $permohonan->update([
                'status' => 'survey-completed',
            ]);

            $penilaian = Penilaian::where('nomor_registrasi', $permohonan->nomor_registrasi)->first();

            $penilaian->update([
                'status' => 'survey-completed',
                'updated_at' => now(),
            ]);


            if (in_array(strtolower($permohonan->jenisPenilaian->name), ['external', 'eksternal'])) {
                LaporanExternal::updateOrCreate(
                    ['permohonan_id' => $permohonan->id],
                    [
                        'nomor_laporan'   => $permohonan->nomor_registrasi,
                        'tgl_final_laporan' => now(),
                        'created_by'      => Auth::id(),
                    ]
                );
            }


            return response()->json([
                'success' => true,
                'message' => 'Form surveyor berhasil disubmit'
            ], 200);

        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Terjadi kesalahan',
                'error' => $e->getMessage()
            ], 500);
        }
    }


    public function checkButtonStatus($id)
    {
        try {
            // Get all inspeksi records for this permohonan
            $inspeksiRecords = Inspeksi::with(['dokument.jenisJaminan'])
            ->where('permohonan_id', $id)
            ->get();

            if ($inspeksiRecords->isEmpty()) {
                return response()->json(['buttonDisable' => true]);
            }

            $rapComplete = false;
            foreach ($inspeksiRecords as $inspeksi) {
                if (strtolower($inspeksi->name) === 'rap') {
                    $dataForm = json_decode($inspeksi->data_form, true);
                    $fotoForm = json_decode($inspeksi->foto_form, true);
                    $isInvalid =  empty($dataForm) &&
                    empty($fotoForm);
                    if ($isInvalid) {
                        return response()->json(['buttonDisable' => true]);
                    }
                } else {
                    $dataForm = json_decode($inspeksi->data_form, true);
                    $fotoForm = json_decode($inspeksi->foto_form, true);
                    $denahForm = json_decode($inspeksi->denah_form, true);
                    $dataPembanding = json_decode($inspeksi->data_pembanding, true);

                    $jenisJaminan = $inspeksi->dokument->jenisJaminan->name ?? '';

                    $isTanahBangunan = !in_array(
                        strtoupper($jenisJaminan ?? ''),
                        ['KAPAL', 'PESAWAT', 'KENDARAAN', 'ALAT BERAT', 'MESIN']
                    );

                    $isInvalid =
                    empty($dataForm) ||
                    empty($fotoForm) ||
                    (($isTanahBangunan && empty($denahForm)) ||
                    empty($dataPembanding));

                    if ($isInvalid) {
                        return response()->json(['buttonDisable' => true]);
                    }
                }
            }
            // If we get here, all checks passed
            return response()->json(['buttonDisable' => false]);

        } catch (\Exception $e) {
            return response()->json([
                'error' => 'Something went wrong',
                'message' => $e->getMessage(),
                'buttonDisable' => true
            ], 500);
        }
    }


    public function storeJadwal(Request $request, $id)
    {
        try {
            $validate = $request->validate([
                'id' => 'required',
                'waktu_penilaian' => 'required',
                'deskripsi_penilaian' => 'required',
                'keterangan' => 'required',
            ]);


            $penilaian = Penilaian::findOrFail($id);

            $permohonan = Permohonan::where('nomor_registrasi', $penilaian->nomor_registrasi)->first();
            ;
            if (Carbon::parse($validate['waktu_penilaian']) <= Carbon::parse($penilaian->tanggal_kunjungan)) {
                return response()->json([
                    'success' => false,
                    'message' => 'Waktu penilaian harus lebih besar dari tanggal assign.'
                ], 422);
            }


            $emailData = [
                'email' => $penilaian->permohonan->user->email,
                'subject' => 'Jadwal Kunjungan',
                'emailData' => $validate,

            ];

            SendJadwalKunjunganEmailJob::dispatch($emailData);

            $permohonan->update([
                'status' => 'request-jadwal',
            ]);


            $penilaian->update([
                'waktu_penilaian' => $validate['waktu_penilaian'],
                'deskripsi_penilaian' => $validate['deskripsi_penilaian'],
            ]);
            return response()->json([
                'success' => true,
                'message' => 'Berhasil kirim jadwal kunjungan'
            ], 200);
        } catch (\Exception $e) {

            return response()->json([
                'success' => false,
                'message' => 'Terjadi kesalahan',
                'error' => $e->getMessage()
            ], 500);
        }
    }


    public function storeFreeze($id, Request $request)
    {
        try {
            $permohonan = Permohonan::findOrFail($id);

            $permohonan->update([
                'keterangan' => $request->keterangan,
                'status' => 'request-freeze',
            ]);

            Authorization::updateOrCreate([
                'permohonan_id' => $permohonan->id,
                'jenis' => 'sla',
            ], [
                'keterangan' => $request->keterangan,
                'request' => 'freeze',
                'user_id' => Auth::user()->id
            ]);

            return response()->json([
                'success' => true,
                'message' => 'Berhasil Kirim permintaan Request Freeaze ke So'
            ], 200);

        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Terjadi kesalahan',
                'error' => $e->getMessage()
            ], 500);
        }

    }


    private function formatDataPembanding($request)
    {
        $dataPembanding = [];
        $pembandingCount = count($request->input('address_pembanding', []));
        $fotoPembanding = $request->file('foto_objek_pembanding') ?? [];

        $existingData = null;
        if ($request->has('permohonan_id') && $request->has('dokument_id')) {
            $inspeksi = Inspeksi::where('permohonan_id', $request->input('permohonan_id'))
                ->where('dokument_id', $request->input('dokument_id'))
                ->first();

            if ($inspeksi) {
                $existingData = json_decode($inspeksi->data_pembanding, true) ?? [];
            }
        }

        for ($i = 0; $i < $pembandingCount; $i++) {
            $pembanding = $this->formatSinglePembanding($request, $i);


            $existingFoto = null;
            if ($existingData && isset($existingData['data_pembanding'][$i]['foto_objek'])) {
                $existingFoto = $existingData['data_pembanding'][$i]['foto_objek'];
            }

            // Penanganan foto pembanding
            if (isset($fotoPembanding[$i]) && $fotoPembanding[$i]->isValid()) {
                $pembanding['foto_objek'] = $this->handleupdateOrDeleteFile(
                    $fotoPembanding[$i],
                    'pembanding',
                    "pembanding_{$i}"
                );
            } else {
                $pembanding['foto_objek'] = $existingFoto;
            }

            $dataPembanding[] = $pembanding;
        }

        return $dataPembanding;
    }


    private function formatSinglePembanding($request, $index)
    {
        $tanahBangunanTypes = ['KAPAL', 'PESAWAT', 'KENDARAAN', 'ALAT BERAT', 'MESIN'];

        $action = isset($request->action) ? strtoupper(str_replace('-', ' ', $request->action)) : '';

        if (in_array($action, $tanahBangunanTypes)) {
            $fields = [
                'address', 'village_code', 'district_code', 'city_code', 'province_code',
                'nama', 'type','warna','lokasi', 'total', 'diskon', 'harga_diskon',
                'sumber_data', 'harga', 'tahun','transmisi','telepon',
                'kordinat_lat', 'kordinat_lng', 'tahun_pembuatan','merek_buatan','kapasitas','power','kondisi','tanggal', 'harga_penawaran'
            ];


        } else {
            $fields = [
                'address', 'village_code', 'district_code', 'city_code', 'province_code',
                'tahun', 'luas_tanah', 'luas_bangunan', 'tahun_bangunan',
                'status_nara_sumber', 'harga', 'harga_diskon', 'diskon', 'total', 'nama_nara_sumber',
                'peruntukan', 'penawaran', 'telepon','hak_properti',
                'kordinat_lat', 'kordinat_lng', 'jenis_aset','foto_objek','tanggal', 'harga_penawaran'
            ];
        }

        $pembanding = [];
        foreach ($fields as $field) {
            $inputName = "{$field}_pembanding";
            $inputValue = $request->input($inputName);

            // Pastikan input adalah array dan index valid
            if (is_array($inputValue) && isset($inputValue[$index])) {
                $value = $inputValue[$index];
                // Format hanya untuk harga, harga_diskon, dan total
                if (in_array($field, ['harga', 'harga_diskon', 'total', 'harga_penawaran'])) {
                    $value = preg_replace('/[^0-9]/', '', $value); // Hapus karakter non-angka
                }
                $pembanding[$field] = $value;
            } else {
                $pembanding[$field] = null;
            }
        }


        return $pembanding;
    }



    private function handleupdateOrDeleteFile($file, $type, $prefix)
    {
        try {
            if ($file) {
                // Generate nama file unik
                $fileName = $prefix . '_' . uniqid() . '_' . time() . '.' . $file->getClientOriginalExtension();
                $path = "{$type}/" . date('Y/m');
                Storage::makeDirectory("public/{$path}");
                $filePath = $file->storeAs("public/{$path}", $fileName);
                return str_replace('public/', '', $filePath);
            }

            return null;

        } catch (\Exception $e) {
            Log::error('File upload error: ' . $e->getMessage());
            throw new \Exception("Gagal mengupload file: " . $e->getMessage());
        }
    }


    private function formatObjekPenilaian($request)
    {
        $fields = [
            'address', 'village_code', 'district_code', 'city_code', 'province_code',
            'luas_tanah', 'luas_tanah_bagunan', 'total', 'diskon', 'harga_diskon',
            'status_nara_sumber', 'harga', 'nama_nara_sumber','hak_properti','telepon',
            'kordinat_lat', 'kordinat_lng', 'jenis_aset','penawaran',  'tanggal','harga_penawaran'
        ];

        $inspeksi = Inspeksi::where('permohonan_id', $request->input('permohonan_id'))
            ->where('dokument_id', $request->input('dokument_id'))
            ->first();

        if ($inspeksi) {
            $needsSave = false;

            // Handle foto_form
            $fotoForm = json_decode($inspeksi->foto_form, true) ?: [];
            if (!isset($fotoForm['object_jaminan'])) {
                $fotoForm['object_jaminan'] = [['foto_objek' => null]];
                $needsSave = true;
            }

            // Handle data_form
            $dataForm = json_decode($inspeksi->data_form, true) ?: [];

            // Inisialisasi struktur data jika belum ada
            if ($request->filled('luas_tanah_bagunan')) {
                if (!isset($dataForm['bangunan'])) {
                    $dataForm['bangunan'] = [];
                }

                if (!isset($dataForm['bangunan']['luas_tanah_bagunan'])) {
                    $dataForm['bangunan']['luas_tanah_bagunan'] = [];
                }

                $cekBanguan = isset($dataForm['bangunan']['luas_tanah_bagunan']['sesuai']) && $dataForm['bangunan']['luas_tanah_bagunan']['sesuai'] === 'sesuai'
                    ? 'sesuai'
                    : 'tidak sesuai';

                $dataForm['bangunan']['luas_tanah_bagunan'][$cekBanguan] = $request->input('luas_tanah_bagunan');
                $needsSave = true;
            }


            if ($request->filled('luas_tanah')) {
                if (!isset($dataForm['tanah'])) {
                    $dataForm['tanah'] = [];
                }

                if (!isset($dataForm['tanah']['luas_tanah'])) {
                    $dataForm['tanah']['luas_tanah'] = [];
                }

                $cekLuas = isset($dataForm['tanah']['luas_tanah']['sesuai']) && $dataForm['tanah']['luas_tanah']['sesuai'] === 'sesuai'
                    ? 'sesuai'
                    : 'tidak sesuai';

                $dataForm['tanah']['luas_tanah'][$cekLuas] = $request->input('luas_tanah');
                $needsSave = true;
            }

            if (!isset($dataForm['asset'])) {
                $dataForm['asset'] = [];
                $needsSave = true;
            }

            // Update data dengan mempertahankan struktur sesuai/tidak sesuai
            foreach ($fields as $field) {
                if ($request->filled($field)) {
                    $newValue = $request->input($field);

                    if (in_array($field, ['harga', 'harga_diskon', 'total'])) {
                        $newValue = preg_replace('/[^0-9]/', '', $newValue);
                    }
                    // Fields untuk tanah
                    if (in_array($field, ['luas_tanah'])) {
                        // Pastikan struktur array ada sebelum diakses
                        if (!isset($dataForm['tanah']['luas_tanah'])) {
                            $dataForm['tanah']['luas_tanah'] = [];
                        }

                        $cekLuas = isset($dataForm['tanah']['luas_tanah']['sesuai']) && $dataForm['tanah']['luas_tanah']['sesuai'] === 'sesuai'
                            ? 'sesuai'
                            : 'tidak sesuai';

                        $dataForm['tanah']['luas_tanah'][$cekLuas] = $newValue;
                        $needsSave = true;
                    }

                    // Fields untuk bangunan
                    elseif (in_array($field, ['luas_tanah_bagunan'])) {
                        if (!isset($dataForm['bangunan']['luas_tanah_bagunan'])) {
                            $dataForm['bangunan']['luas_tanah_bagunan'] = [];
                        }

                        $cekBanguan = isset($dataForm['bangunan']['luas_tanah_bagunan']['sesuai']) && $dataForm['bangunan']['luas_tanah_bagunan']['sesuai'] === 'sesuai'
                            ? 'sesuai'
                            : 'tidak sesuai';

                        $dataForm['bangunan']['luas_tanah_bagunan'][$cekBanguan] = $newValue;
                        $needsSave = true;
                    }

                    // Fields untuk alamat dalam asset
                    // Fields untuk alamat dalam asset
                    elseif (in_array($field, ['address', 'village_code', 'district_code', 'city_code', 'province_code'])) {
                        if (!isset($dataForm['asset']['alamat'])) {
                            $dataForm['asset']['alamat'] = [
                                'sesuai' => [
                                    'address' => '',
                                    'village_code' => '',
                                    'district_code' => '',
                                    'city_code' => '',
                                    'province_code' => ''
                                ]
                            ];
                        }

                        // Tentukan status alamat (sesuai/tidak sesuai)
                        $alamatStatus = isset($dataForm['asset']['alamat']['sesuai']) ? 'sesuai' : 'tidak sesuai';

                        // Update nilai dalam status yang ada
                        if (!isset($dataForm['asset']['alamat'][$alamatStatus])) {
                            $dataForm['asset']['alamat'][$alamatStatus] = [];
                        }

                        // Update nilai field yang sesuai
                        $dataForm['asset']['alamat'][$alamatStatus][$field] = $newValue;
                    }

                    // Jenis asset dalam asset
                    elseif ($field === 'jenis_asset') {
                        $assetStatus = $request->input('asset_status', 'sesuai');
                        $dataForm['asset']['jenis_asset'] = [
                            $assetStatus => $newValue
                        ];
                    }
                    // Fields lainnya dalam asset
                    else {
                        if (!isset($dataForm['asset'][$field])) {
                            $dataForm['asset'][$field] = [];
                        }
                        $dataForm['asset'][$field] = $newValue;
                    }


                    $needsSave = true;
                }
            }

            if ($needsSave) {
                $inspeksi->foto_form = json_encode($fotoForm);
                $inspeksi->data_form = json_encode($dataForm);
                $inspeksi->save();
            }

            $existingFoto = $fotoForm['object_jaminan'][0]['foto_objek'] ?? null;

            // Gabungkan data dari tanah, bangunan, dan asset
            $objekPenilaian = array_merge(
                ['foto_objek' => $existingFoto],
                $dataForm['tanah'] ?? [],
                $dataForm['bangunan'] ?? [],
                array_reduce($fields, function ($carry, $field) use ($request, $dataForm) {
                    if (isset($dataForm['asset'][$field])) {
                        if (is_array($dataForm['asset'][$field])) {
                            if (isset($dataForm['asset'][$field]['sesuai'])) {
                                $carry[$field] = $dataForm['asset'][$field]['sesuai'];
                            } elseif (isset($dataForm['asset'][$field]['tidak sesuai'])) {
                                $carry[$field] = $dataForm['asset'][$field]['tidak sesuai'];
                            }
                        } else {
                            $carry[$field] = $dataForm['asset'][$field];
                        }
                    } else {
                        $carry[$field] = $request->input($field);
                    }
                    return $carry;
                }, [])
            );

        } else {
            // Inisialisasi data baru
            $objekPenilaian = array_reduce($fields, function ($carry, $field) use ($request) {
                $carry[$field] = $request->input($field);
                return $carry;
            }, ['foto_objek' => null]);
        }

        return $objekPenilaian;
    }

    private function formatObjekPenilaiankendaraan($request)
    {
        $fields = [
            'address', 'village_code', 'district_code', 'city_code', 'province_code',
            'nama', 'type','warna','lokasi', 'total', 'diskon', 'harga_diskon',
            'sumber_data', 'harga', 'tahun','transmisi','telepon',
            'kordinat_lat', 'kordinat_lng', 'tahun_pembuatan','merek_buatan','kapasitas','power','kondisi'
        ];

        $inspeksi = Inspeksi::where('permohonan_id', $request->input('permohonan_id'))
            ->where('dokument_id', $request->input('dokument_id'))
            ->first();

        if ($inspeksi) {
            $needsSave = false;

            // Handle foto_form
            $fotoForm = json_decode($inspeksi->foto_form, true) ?: [];
            if (!isset($fotoForm['object_jaminan'])) {
                $fotoForm['object_jaminan'] = [['foto_objek' => null]];
                $needsSave = true;
            }

            // Handle data_form
            $dataForm = json_decode($inspeksi->data_form, true) ?: [];


            // Update data dengan mempertahankan struktur sesuai/tidak sesuai
            foreach ($fields as $field) {
                if ($request->filled($field)) {
                    $newValue = $request->input($field);
                    if (in_array($field, ['harga', 'harga_diskon', 'total'])) {
                        $newValue = preg_replace('/[^0-9]/', '', $newValue);
                    }
                    // Fields untuk alamat dalam asset
                    if (in_array($field, ['address', 'village_code', 'district_code', 'city_code', 'province_code'])) {

                        if (!isset($dataForm['alamat'])) {
                            $dataForm['alamat'] = [];
                        }

                        $alamatStatus = $dataForm['alamat'] == 'sesuai' ? 'sesuai' : 'tidak sesuai';
                        if (!isset($dataForm['alamat'][$alamatStatus])) {
                            $dataForm['alamat'][$alamatStatus] = [];
                        }

                        $dataForm['alamat'][$alamatStatus][$field] = $newValue;
                    } else {
                        if (!isset($dataForm[$field])) {
                            $dataForm[$field] = [];
                        }
                        $dataForm[$field] = $newValue;
                    }


                    $needsSave = true;
                }
            }

            if ($needsSave) {
                $inspeksi->foto_form = json_encode($fotoForm);
                $inspeksi->data_form = json_encode($dataForm);
                $inspeksi->save();
            }

            $existingFoto = $fotoForm['object_jaminan'][0]['foto_objek'] ?? null;

            // Gabungkan data dari tanah, bangunan, dan asset
            $objekPenilaian = array_merge(
                ['foto_objek' => $existingFoto],
                array_reduce($fields, function ($carry, $field) use ($request, $dataForm) {
                    if (isset($dataForm[$field])) {
                        if (is_array($dataForm[$field])) {
                            if (isset($dataForm[$field]['sesuai'])) {
                                $carry[$field] = $dataForm[$field]['sesuai'];
                            } elseif (isset($dataForm[$field]['tidak sesuai'])) {
                                $carry[$field] = $dataForm[$field]['tidak sesuai'];
                            }
                        } else {
                            $carry[$field] = $dataForm[$field];
                        }
                    } else {
                        $carry[$field] = $request->input($field);
                    }
                    return $carry;
                }, [])
            );

        } else {
            // Inisialisasi data baru
            $objekPenilaian = array_reduce($fields, function ($carry, $field) use ($request) {
                $carry[$field] = $request->input($field);
                return $carry;
            }, ['foto_objek' => null]);
        }

        return $objekPenilaian;
    }



    private function saveInspeksi($formattedData)
    {
        $inspeksi = Inspeksi::updateOrCreate(
            [
                'permohonan_id' => $formattedData['permohonan_id'],
                'dokument_id' => $formattedData['dokument_id']
            ],
            [
                'data_pembanding' => json_encode($formattedData),
                'name' => $formattedData['type']
            ]
        );

        return $inspeksi;
    }
    public function storeDataPembanding(Request $request)
    {
        $request->merge([
            'kordinat_lat' => $request->get('kordinat_lat') ? str_replace(',', '', $request->get('kordinat_lat')) : null,
            'kordinat_lng' => $request->get('kordinat_lng') ? str_replace(',', '', $request->get('kordinat_lng')) : null,
        ]);

        try {
            DB::beginTransaction();

            // dd($request->all());
            $maxSize = getMaxFileSize('Foto');
            $validator = $request->validate(
                [
                'permohonan_id' => 'required|exists:permohonan,id',
                'type' => 'nullable|string',
                'dokument_id' => 'required',
                'name_foto_objek' => 'nullable|string',
                'nomor_registrasi' => 'required|string',
                'kordinat_lat' => [
                    'nullable',
                    'regex:/^(-?[1-8]?[0-9](\.\d+)?|90(\.0+)?)$/'
                ],
                'kordinat_long' => [
                    'nullable',
                    'regex:/^(-?(1[0-7][0-9]|[1-9]?[0-9])(\.\d+)?|180(\.0+)?)$/'
                ],
                'kordinat_lat_pembanding.*' => [
                    'nullable',
                    'regex:/^(-?[1-8]?[0-9](\.\d+)?|90(\.0+)?)$/'
                ],
                'kordinat_lng_pembanding.*' => [
                    'nullable',
                    'regex:/^(-?(1[0-7][0-9]|[1-9]?[0-9])(\.\d+)?|180(\.0+)?)$/'
                ],
            ],
                [
                'kordinat_lat.regex' => 'Format koordinat latitude tidak valid.',
                'kordinat_long.regex' => 'Format koordinat longitude tidak valid.',
                'kordinat_lat_pembanding.*.regex' => 'Format koordinat latitude pembanding tidak valid.',
                'kordinat_lng_pembanding.*.regex' => 'Format koordinat longitude pembanding tidak valid.',
            ]
            );

            $tanahBangunanTypes = ['KAPAL', 'PESAWAT', 'KENDARAAN', 'ALAT BERAT', 'MESIN'];

            $action = isset($request->action) ? strtoupper(str_replace('-', ' ', $request->action)) : '';

            if (in_array($action, $tanahBangunanTypes)) {

                $objekPenilaian = $this->formatObjekPenilaiankendaraan($request);
            } else {
                $objekPenilaian = $this->formatObjekPenilaian($request);
            }
            if ($request->hasFile('foto_objek')) {
                $newFoto = $this->handleEditTampakDepan($request);
                $objekPenilaian['foto_objek'] = $newFoto;
            }


            $formattedData = [
                'permohonan_id' => $request->input('permohonan_id'),
                'type' => $request->input('type'),
                'dokument_id' => $request->input('dokument_id'),
                'objek_penilaian' => $objekPenilaian,
                'data_pembanding' => $this->formatDataPembanding($request),
                'keterangan' => $request->input('keterangan')
            ];


            $inspeksi = $this->saveInspeksi($formattedData);

            DB::commit();

            return response()->json([
                'success' => true,
                'message' => 'Data berhasil disimpan',
                'data' => $formattedData
            ], 200);

        } catch (\Exception $e) {
            DB::rollBack();
            return response()->json([
                'success' => false,
                'message' => 'Gagal menyimpan data: ' . $e->getMessage()
            ], 500);
        }
    }

    public function handleEditTampakDepan(Request $request)
    {

        $nomor_registrasi = $request->nomor_registrasi;

        // Ambil data inspeksi
        $inspeksi = Inspeksi::where('permohonan_id', $request->input('permohonan_id'))
            ->where('dokument_id', $request->input('dokument_id'))
            ->firstOrFail();

        // Bersihkan path dari request
        $cleanRequestPath = str_replace('/storage/', '', $request['path']);

        // Ambil foto_form dari inspeksi
        $fotoForm = json_decode($inspeksi->foto_form, true) ?? [];
        $fotoForm['upload_foto'] = $fotoForm['upload_foto'] ?? [];

        $existingIndex = null;
        if (!empty($request['path'])) {
            foreach ($fotoForm['upload_foto'] as $index => $foto) {
                if ($foto['path'] === $cleanRequestPath) {
                    $existingIndex = $index;
                    break;
                }
            }
        }

        if ($request->hasFile('foto_objek')) {
            $file = $request->file('foto_objek');
            $timestamp = time();
            $originalName = $file->getClientOriginalName();
            $extension = $file->getClientOriginalExtension();

            // Validasi nama file
            if (empty($originalName)) {
                $originalName = "file_{$timestamp}";
            }
            $uniqueFileName = "{$timestamp}.{$extension}";

            // Simpan file ke penyimpanan publik
            $path = $file->storeAs("surveyor/upload_foto/{$nomor_registrasi}", $uniqueFileName, 'public');

            // Data baru untuk foto
            $newFotoData = [
                'name' => $originalName,
                'description' => null,
                'category' => 'Tampak Depan',
                'sub' => null,
                'path' => $path,
                'created_by' => Auth::user()->name,
                'created_at' => now()->toDateTimeString(),
                'updated_by' => Auth::user()->name,
                'updated_at' => now()->toDateTimeString(),
            ];

            // Update atau tambahkan data baru
            if ($existingIndex !== null) {
                $fotoForm['upload_foto'][$existingIndex] = $newFotoData;
            } else {
                $fotoForm['upload_foto'][] = $newFotoData;
            }

            // Simpan kembali data ke database
            $inspeksi->foto_form = json_encode($fotoForm);
            $inspeksi->save();

            return $path;
        }
    }

    /**
     * Form inspeksi.
     */

    public function formInspeksi(Request $request, $id)
    {

        $validated = $request->validate([
            'documentId' => 'required',
            'jenis_jaminan' => 'required'
        ]);

        $dokumentId = $validated['documentId'];
        $jaminanId = $validated['jenis_jaminan'];

        $permohonan = $this->getPermohonanJaminanId($id, $dokumentId, $jaminanId);

        $link_url_region = Teams::with('regions', 'teamsUsers')
            ->whereHas('teamsUsers', function ($query) {
                $query->where('user_id', Auth::user()->id);
            })->first();

        $branches  = Branch::all();
        $provinces = Province::all();



        $surveyor = $id;
        $basicData = $this->getCommonData();

        $inpeksi = Inspeksi::where('permohonan_id', $id)->where('dokument_id', $dokumentId)->first();
        $forminspeksi = null;
        if ($inpeksi) {
            $forminspeksi = json_decode($inpeksi->data_form, true);
        }

        // Default: gunakan data dari debitur
        $debitur = Debiture::find($permohonan->debiture_id);

        $provinceCode = $debitur->province_code;
        $cityCode     = $debitur->city_code;
        $districtCode = $debitur->district_code;

        // Jika alamat tidak sesuai, override dengan kode dari alamat

        $cekAlamat = $forminspeksi['asset']['alamat']['tidak sesuai'] ?? $forminspeksi['asset']['alamat']['sesuai'] ?? [];

        if ($cekAlamat) {
            $provinceCode = $cekAlamat['province_code'] ?? $provinceCode;
            $cityCode     = $cekAlamat['city_code'] ?? $cityCode;
            $districtCode = $cekAlamat['district_code'] ?? $districtCode;
            // Ambil data menggunakan kode yang telah ditentukan

        }
        $cities    = City::where('province_code', $provinceCode)->get();
        $districts = District::where('city_code', $cityCode)->get();
        $villages  = Village::where('district_code', $districtCode)->get();

        if ($forminspeksi) {
            if (isset($forminspeksi['alamat']['sesuai']['province_code'])) {
                $cities = City::where('province_code', $forminspeksi['alamat']['sesuai']['province_code'])->get();
            }

            if (isset($forminspeksi['alamat']['sesuai']['city_code'])) {
                $districts = District::where('city_code', $forminspeksi['alamat']['sesuai']['city_code'])->get();
            }

            if (isset($forminspeksi['alamat']['sesuai']['district_code'])) {
                $villages = Village::where('district_code', $forminspeksi['alamat']['sesuai']['district_code'])->get();
            }
        }


        return view('lpj::surveyor.components.inspeksi', compact(
            'permohonan',
            'surveyor',
            'branches',
            'provinces',
            'debitur',
            'cities',
            'districts',
            'villages',
            'link_url_region',
            'forminspeksi',
            'basicData',
            'cekAlamat'
        ));
    }

    /**
     * Denah.
     */

    public function denah(Request $request, $id)
    {
        $validated = $request->validate([
          'documentId' => 'required',
          'jenis_jaminan' => 'required'
        ]);

        $dokumentId = $validated['documentId'];
        $jaminanId = $validated['jenis_jaminan'];

        $permohonan = $this->getPermohonanJaminanId($id, $dokumentId, $jaminanId);

        $denah = null;

        $inpeksi = Inspeksi::where('permohonan_id', $id)->where('dokument_id', $dokumentId)->first();
        $formDenah = null;
        if ($inpeksi) {
            $formDenah = json_decode($inpeksi->denah_form, true);
        }

        // return response()->json($formDenah);
        return view('lpj::surveyor.components.denah', compact('permohonan', 'denah', 'formDenah'));
    }

    /**
     * Foto.
     */

    public function foto(Request $request, $id)
    {
        $validated = $request->validate([
            'documentId' => 'required',
            'jenis_jaminan' => 'required'
        ]);

        $dokumentId = $validated['documentId'];
        $jaminanId = $validated['jenis_jaminan'];
        $fotoObjekJaminan = FotoObjekJaminan::all();

        $permohonan = $this->getPermohonanJaminanId($id, $dokumentId, $jaminanId);


        $surveyor = $id;
        $branches  = Branch::all();
        $provinces = Province::all();

        $inpeksi = Inspeksi::where('permohonan_id', $id)->where('dokument_id', $dokumentId)->first();

        $formFoto = null;
        if ($inpeksi) {
            $formFoto = json_decode($inpeksi->foto_form, true);
        }
        $fotoJaminan = null;
        return view('lpj::surveyor.components.foto', compact('permohonan', 'surveyor', 'branches', 'provinces', 'fotoJaminan', 'formFoto', 'fotoObjekJaminan'));
    }

    /**
     * Data pembanding.
     */

    public function dataPembanding(Request $request, $id)
    {
        try {
            // Ambil data permohonan dengan eager loading

            $validated = $request->validate([
                'documentId' => 'required',
                'jenis_jaminan' => 'required'
            ]);

            $dokumentId = $validated['documentId'];
            $jaminanId = $validated['jenis_jaminan'];

            $permohonan = $this->getPermohonanJaminanId($id, $dokumentId, $jaminanId);


            // Ambil data inspeksi
            $inspeksi = Inspeksi::where([
                'permohonan_id' => $id,
                'dokument_id' => $dokumentId
            ])->first();

            // Inisialisasi variabel
            $inspectionData = null;
            $comparisons = null;
            $fotoForm = null;


            if ($inspeksi) {

                $inspectionData = json_decode($inspeksi->data_form, true);
                if (json_last_error() !== JSON_ERROR_NONE) {
                    throw new \Exception('Harap mengisi form inspeksi terlebih dahulu.');
                }

                if ($inspeksi->data_pembanding) {
                    $comparisons = json_decode($inspeksi->data_pembanding, true);
                    if (json_last_error() !== JSON_ERROR_NONE) {
                        throw new \Exception('Error decoding comparison data: ' . json_last_error_msg());
                    }
                }
                $fotoForm = json_decode($inspeksi->foto_form, true);

            }

            // Ambil data pendukung
            $data = $this->getCommonData();
            $provinces = Province::all();

            $cities          = City::where('province_code', $this->getCodeAlamat('province_code', $inspectionData))->get();
            $districts       = District::where('city_code', $this->getCodeAlamat('city_code', $inspectionData))->get();
            $villages        = Village::where('district_code', $this->getCodeAlamat('district_code', $inspectionData))->get();

            return view('lpj::surveyor.components.data-pembanding', compact(
                'permohonan',
                'id',
                'inspectionData',
                'comparisons',
                'data',
                'jaminanId',
                'fotoForm',
                'cities',
                'districts',
                'villages',
                'provinces',
                'inspeksi'
            ));

        } catch (\Exception $e) {
            return redirect()
                ->back()
                ->with('error', 'Terjadi kesalahan saat memuat data: ' . $e->getMessage());
        }
    }


    public function getCodeAlamat($code, $inspectionData)
    {

        $tanahBangunanTypes = ['KAPAL', 'PESAWAT', 'KENDARAAN', 'ALAT BERAT', 'MESIN'];

        $action = isset($inspectionData['action']) ? strtoupper(str_replace('-', ' ', $inspectionData['action'])) : '';

        if (in_array($action, $tanahBangunanTypes)) {
            return $selectedProvince = $inspectionData['alamat']['sesuai'][$code] ?? null;
        }

        if (isset($inspectionData['asset'])) {
            $cekAlamat = isset($inspectionData['asset']['alamat']['sesuai']) ? 'sesuai' : 'tidak sesuai';
            $selectedProvince = $inspectionData['asset']['alamat'][$cekAlamat][$code] ?? null;
            return $selectedProvince;
        }
        return null;

    }


    private function getHeader(string $type): array
    {
        return self::HEADERS[$type] ?? [];
    }

    public function data(Request $request)
    {

        $type = $request->route('type');
        $header = $this->getHeader($request->route('type'));
        return view('lpj::surveyor.data.index', compact('header'));
    }


    public function createData($type)
    {
        $spekKategoriBagunan = SpekKategoritBangunan::all();
        $header = $this->getHeader($type);
        return view('lpj::surveyor.data.form', compact('header', 'spekKategoriBagunan'));
    }


    public function storeData(SurveyorRequest $request, $type)
    {
        $validate = $request->validated();
        if ($validate) {

            try {
                $type = $request->route('type');

                $modelClass = $this->getModelClass($type);

                if (!$modelClass) {
                    return redirect()
                        ->route('basicdata.' . $type . '.index')
                        ->with('error', 'Invalid type specified.');
                }

                if ($type == 'spek-bangunan') {
                    $validate['spek_kategori_bagunan_id'] = $request->spek_kategori_bagunan_id;
                }


                $data = array_merge($validate, ['status' => true]);
                $modelClass::create($data);

                return redirect()
                    ->route('basicdata.' . $type . '.index')
                    ->with('success', 'created successfully');
            } catch (\Exception $e) {
                return redirect()
                    ->route('basicdata.' . $type . '.index')
                    ->with('error', $e->getMessage());
            }
        }
    }


    public function editData($type, $id)
    {
        $dataMap = [
            'bentuk-tanah' => ['Bentuk Tanah', 'bentuk-tanah', BentukTanah::class],
            'kontur-tanah' => ['Kontur Tanah', 'kontur-tanah', KonturTanah::class],
            'posisi-kavling' => ['Posisi Kavling', 'posisi-kavling', PosisiKavling::class],
            'ketinggian-tanah' => ['Ketinggian Tanah', 'ketinggian-tanah', KetinggianTanah::class],
            'kondisi-fisik-tanah' => ['Kondisi Fisik Tanah', 'kondisi-fisik-tanah', KondisiFisikTanah::class],
            'jenis-bangunan' => ['Jenis Bangunan', 'jenis-bangunan', JenisBangunan::class],
            'kondisi-bangunan' => ['Kondisi Bangunan', 'kondisi-bangunan', KondisiBangunan::class],
            'sifat-bangunan' => ['Sifat Bangunan', 'sifat-bangunan', SifatBangunan::class],
            'spek-bangunan' => ['Spek Bangunan', 'spek-bangunan', SpekBangunan::class],
            'spek-kategori-bangunan' => ['Spek Kategori Bangunan', 'spek-kategori-bangunan', SpekKategoritBangunan::class],
            'sarana-pelengkap' => ['Sarana Pelengkap', 'sarana-pelengkap', SaranaPelengkap::class],
            'lantai-unit' => ['Lantai Unit', 'lantai-unit', Lantai::class],
            'view-unit' => ['View Unit', 'view-unit', ViewUnit::class],
            'gol-mas-sekitar' => ['Golongan Masyarakat Sekitar', 'gol-mas-sekitar', GolonganMasySekitar::class],
            'jenis-pesawat' => ['Jenis Pasawat', 'jenis-pesawat', JenisPesawat::class],
            'model-alat-berat' => ['Model Alat Berat', 'model-alat-berat', ModelAlatBerat::class],
            'jenis-kapal' => ['Jenis Kapal', 'jenis-kapal', JenisKapal::class],
            'jenis-kendaraan' => ['Jenis Kendaraan', 'jenis-kendaraan', JenisKendaraan::class],
            'jenis-unit' => ['Jenis unit', 'jenis-unit', JenisUnit::class],
            'terletak-area' => ['Terletak di Area', 'terletak-area', TerletakArea::class],
            'merupakan-daerah' => ['Merupakan Daerah', 'merupakan-daerah', MerupakanDaerah::class],
            'posisi-unit' => ['Posisi unit', 'posisi-unit', PosisiUnit::class],
            'bentuk-unit' => ['Bentuk unit', 'bentuk-unit', BentukUnit::class],
            'fasilitas-objek' => ['Fasilitas Umum Dekat Objek', 'fasilitas-objek', FasilitasObjek::class],
            'foto-objek-jaminan' => ['Foto Objek Jaminan', 'foto-objek-jaminan', FotoObjekJaminan::class],
        ];


        if (!array_key_exists($type, $dataMap)) {
            return redirect()->back()->with('error', 'Invalid type specified.');
        }

        [$headers, $routeName, $modelClass] = $dataMap[$type];

        $header = $dataMap[$type] ?? '';
        $model = $modelClass::findOrFail($id);

        $spekKategoriBagunan = null;
        if ($type == 'spek-bangunan') {
            $spekKategoriBagunan = SpekKategoritBangunan::all();
        }


        return view('lpj::surveyor.data.form', compact('header', 'model', 'spekKategoriBagunan'));
    }


    public function updateData(SurveyorRequest $request, $type, $id)
    {
        $validate = $request->validated();
        if ($validate) {
            $modelClass = $this->getModelClass($type);

            if ($type == 'spek-bangunan') {
                $validate['spek_kategori_bagunan_id'] = $request->spek_kategori_bagunan_id;
            }

            if ($type == 'foto-objek-jaminan') {
                $validate['kategori'] = $request->kategori;
            }

            // Check if the provided type exists in the modelClasses
            if (!$modelClass) {
                return redirect()
                    ->route('basicdata.' . $type . '.index')
                    ->with('error', 'Invalid type specified.');
            }

            $model = $modelClass::findOrFail($id);
            $model->update($validate);

            // Redirect back with a success message
            return redirect()
                ->route('basicdata.' . $type . '.index')
                ->with('success', 'Updated successfully');
        }
    }


    public function update_analisa($id, Request $request)
    {
        try {
            $permohonan = Permohonan::with([
                'user',
                'debiture.province',
                'debiture.city',
                'debiture.district',
                'debiture.village',
                'branch',
                'tujuanPenilaian',
                'penilaian',
                'documents',
            ])->findOrFail($id);

            $jenisAssetUpdated = false;
            if ($request->input('types') == 'jenis_asset') {
                $this->updateJenisAsset($permohonan, $request);
                $jenisAssetUpdated = true;
            }

            if (in_array($request->input('types'), ['analisa_tanah', 'analisa_bangunan', 'analisa_unit'])) {
                $key = match ($request->input('types')) {
                    'analisa_tanah' => 'luas_tanah',
                    'analisa_bangunan' => 'luas_bangunan',
                    'analisa_unit' => 'luas_unit',
                };


                $jenis_jaminan_mapping = [
                    'luas_unit' => $request->input('jenis_legalistas_jaminan_unit_id'),
                    'luas_bangunan' => $request->input('jenis_legalistas_jaminan_bangunan_id'),
                    'luas_tanah' => $request->input('jenis_legalistas_jaminan_tanah_id'),
                ];


                $jenis_jaminan_id = $jenis_jaminan_mapping[$key] ?? 0;
                // dd($jenis_jaminan_id);

                $inputValue = $request->input($key);

                $cleanedValue = preg_replace('/\D/', '', $inputValue);
                $this->updateDetails($permohonan, $key, $cleanedValue, $jenis_jaminan_id);
            }

            return response()->json([
                'success' => true,
                'message' => 'Data berhasil disimpan',
                'jenis_asset' => $jenisAssetUpdated,
            ], 200);
        } catch (\Exception $e) {
            return response()->json(['error' => 'Something went wrong', 'message' => $e->getMessage()], 500);
        }
    }


    private function updateJenisAsset($permohonan, $request)
    {
        $jenis_jaminan_id = $permohonan->documents->first()->jenis_jaminan_id;
        DokumenJaminan::where('permohonan_id', $permohonan->id)
            ->where('jenis_jaminan_id', $jenis_jaminan_id)
            ->update([
                'jenis_jaminan_id' => $request->input('jenis_asset'),
            ]);
    }

    private function updateDetails($permohonan, $key, $newValue, $jenis_jaminan_id)
    {
        $document = $permohonan->documents->first();

        if (!$document) {
            throw new \Exception("Document not found");
        }

        // dd($jenis_jaminan_id);
        $detailsUpdate = DetailDokumenJaminan::where('dokumen_jaminan_id', $document->id)
        ->where('jenis_legalitas_jaminan_id', $jenis_jaminan_id)
        ->first();

        // dd($detailsUpdate);

        if (!$detailsUpdate) {
            throw new \Exception("DetailDokumenJaminan not found");
        }

        $datas = json_decode($detailsUpdate->details, true) ?? [];

        if (!is_scalar($newValue)) {
            throw new \InvalidArgumentException("New value must be a scalar (string/number)");
        }

        // Update nilai berdasarkan kunci
        if (array_key_exists($key, $datas)) {
            $datas[$key] = $newValue;
        } else {
            $datas[$key] = $newValue;
        }

        // Simpan kembali ke database
        $detailsUpdate->update([
            'details' => json_encode($datas),
        ]);
    }


    public function dataForDatatables(Request $request)
    {
        // if (is_null($this->user) || !$this->user->can('debitur.view')) {
        //     abort(403, 'Sorry! You are not allowed to view users.');
        // }

        $query = Permohonan::query();
        $query = $query->orderBy('nomor_registrasi', 'desc');
        if ($request->has('search') && !empty($request->get('search'))) {
            $search = $request->get('search');
            $query->where(function ($q) use ($search) {
                $q->where('nomor_registrasi', 'LIKE', '%' . $search . '%');
                $q->orWhere('tanggal_permohonan', 'LIKE', '%' . $search . '%');
                $q->orWhereRelation('user', 'name', 'LIKE', '%' . $search . '%');
                $q->orWhereRelation('debiture', 'name', 'LIKE', '%' . $search . '%');
                $q->orWhereRelation('tujuanPenilaian', 'name', 'LIKE', '%' . $search . '%');
                $q->orWhereRelation('branch', 'name', 'LIKE', '%' . $search . '%');
                $q->orWhere('status', 'LIKE', '%' . $search . '%');
            });
        }

        $query->whereRaw('LOWER(status) IN (?, ?, ?, ?, ?, ? ,?,?, ?)', ['assign', 'survey', 'proses-survey', 'request-reschedule', 'reschedule', 'rejected-reschedule', 'approved-reschedule', 'revisi-survey', 'request-jadwal' ]);


        if (!Auth::user()->hasRole('administrator')) {
            $query->whereHas('penilaian.userPenilai', function ($q) {
                $q->where('user_id', Auth::user()->id);
                $q->where('role', ['surveyor', 'penilai']);
            });
        }


        if ($request->has('sortOrder') && !empty($request->get('sortOrder'))) {
            $order  = $request->get('sortOrder');
            $column = $request->get('sortField');
            $query->orderBy($column, $order);
        }

        $totalRecords = $query->count();

        $size = $request->get('size', 10);
        if ($size == 0) {
            $size = 10;
        }

        if ($request->has('page') && $request->has('size')) {
            $page   = $request->get('page', 1);
            $offset = ($page - 1) * $size;

            $query->skip($offset)->take($size);
        }

        $filteredRecords = $query->count();
        $data = $query->with(['user', 'debiture', 'branch', 'tujuanPenilaian', 'jenisFasilitasKredit', 'penilaian'])->get();

        $pageCount = ceil($totalRecords / $size);

        $currentPage = max(1, $request->get('page', 1));
        return response()->json([
            'draw'            => $request->get('draw'),
            'recordsTotal'    => $totalRecords,
            'recordsFiltered' => $filteredRecords,
            'pageCount'       => $pageCount,
            'page'            => $currentPage,
            'totalCount'      => $totalRecords,
            'data'            => $data,
        ]);
    }



    public function dataForDatatablesData(Request $request, $type)
    {
        if (is_null(Auth::user()) || !$this->user->can('jenis_aset.view')) {
            //abort(403, 'Sorry! You are not allowed to view users.');
        }

        $models = [
            'Bentuk Tanah' => BentukTanah::class,
            'Kontur Tanah' => KonturTanah::class,
            'Posisi Kavling' => PosisiKavling::class,
            'Ketinggian Tanah' => KetinggianTanah::class,
            'Kondisi Fisik Tanah' => KondisiFisikTanah::class,
            'Jenis Bangunan' => JenisBangunan::class,
            'Kondisi Bangunan' => KondisiBangunan::class,
            'Sifat Bangunan' => SifatBangunan::class,
            'Spek Kategori Bangunan' => SpekKategoritBangunan::class,
            'Spek Bangunan' => SpekBangunan::class,
            'Sarana Pelengkap' => SaranaPelengkap::class,
            'Lalu Lintas Depan Lokasi' => LaluLintasLokasi::class,
            'Tingkat Keramaian' => TingkatKeramaian::class,
            'Golongan Masyarakat Sekitar' => GolonganMasySekitar::class,
            'Lantai Unit' => Lantai::class,
            'View Unit' => ViewUnit::class,
            'Perkerasan jalan' => PerkerasanJalan::class,
            'Jenis pesawat' => JenisPesawat::class,
            'Model alat berat' => ModelAlatBerat::class,
            'Jenis kapal' => JenisKapal::class,
            'Jenis kendaraan' => JenisKendaraan::class,
            'Terletak di Area' => TerletakArea::class,
            'Posisi unit' => PosisiUnit::class,
            'Bentuk unit' => BentukUnit::class,
            'Fasilitas Umum Dekat Objek' => FasilitasObjek::class,
            'Merupakan Daerah' => MerupakanDaerah::class,
            'Jenis unit' => JenisUnit::class,
            'Foto Objek Jaminan' => FotoObjekJaminan::class,
            'Perizinan' => Perizinan::class,
        ];


        if (array_key_exists($type, $models)) {
            $query = $models[$type]::query();
        } else {
            throw new \InvalidArgumentException("Invalid type: $type");
        }

        if ($request->has('search') && !empty($request->get('search'))) {
            $search = $request->get('search');
            $query->where(function ($q) use ($search) {
                $q->where('code', 'LIKE', "%$search%");
                $q->orWhere('name', 'LIKE', "%$search%");
            });
        }

        // Apply sorting if provided
        if ($request->has('sortOrder') && !empty($request->get('sortOrder'))) {
            $order  = $request->get('sortOrder');
            $column = $request->get('sortField');
            $query->orderBy($column, $order);
        }

        // Get the total count of records
        $totalRecords = $query->count();

        // Apply pagination if provided
        if ($request->has('page') && $request->has('size')) {
            $page   = $request->get('page');
            $size   = $request->get('size');
            $offset = ($page - 1) * $size; // Calculate the offset

            $query->skip($offset)->take($size);
        }

        // Get the filtered count of records
        $filteredRecords = $query->count();

        // Get the data for the current page

        if ($type == 'Spek Bangunan') {
            $data = $query->with(['bangunanKategori'])->get();
        } else {
            $data = $query->get();
        }


        // Calculate the page count
        $pageCount = ceil($totalRecords / $request->get('size'));

        // Calculate the current page number
        $currentPage = 0 + 1;


        // Return the response data as a JSON object
        return response()->json([
            'draw'            => $request->get('draw'),
            'recordsTotal'    => $totalRecords,
            'recordsFiltered' => $filteredRecords,
            'pageCount'       => $pageCount,
            'page'            => $currentPage,
            'totalCount'      => $totalRecords,
            'data'            => $data,
        ]);
    }

    public function destroy($id, $type)
    {
        try {

            $modelClass = $this->getModelClass($type);

            if (!$modelClass) {
                return response()->json(['success' => false, 'message' => 'Invalid type specified.'], 400);
            }
            $model = $modelClass::findOrFail($id);
            $model->delete();
            return response()->json(['success' => true, 'message' => 'deleted successfully']);
        } catch (\Illuminate\Database\Eloquent\ModelNotFoundException $e) {
            return response()->json(['success' => false, 'message' => 'not found.'], 404);
        } catch (\Exception $e) {
            return response()->json(['success' => false, 'message' => 'Failed to delete.'], 500);
        }
    }


    public function getPermohonanJaminanId($id, $dokumentId, $jaminanId)
    {
        return Permohonan::with([
            'user',
            'debiture.province',
            'debiture.city',
            'debiture.district',
            'debiture.village',
            'branch',
            'tujuanPenilaian',
            'penilaian',
            'penawaran',
            'debiture.documents' => function ($query) use ($dokumentId, $jaminanId) {
                $query->where('id', $dokumentId)
                      ->where('jenis_jaminan_id', $jaminanId);
            }
            ])->findOrFail($id);
    }




    private function getModelClass(string $type): ?string
    {
        return $this->modelClasses[$type] ?? null;
    }



    private $modelClasses = [
        'bentuk-tanah' => BentukTanah::class,
        'kontur-tanah' => KonturTanah::class,
        'posisi-kavling' => PosisiKavling::class,
        'ketinggian-tanah' => KetinggianTanah::class,
        'kondisi-fisik-tanah' => KondisiFisikTanah::class,
        'jenis-bangunan' => JenisBangunan::class,
        'kondisi-bangunan' => KondisiBangunan::class,
        'sifat-bangunan' => SifatBangunan::class,
        'sarana-pelengkap' => SaranaPelengkap::class,
        'lalu-lintas-lokasi' => LaluLintasLokasi::class,
        'tingkat-keramaian' => TingkatKeramaian::class,
        'gol-mas-sekitar' => GolonganMasySekitar::class,
        'spek-kategori-bangunan' => SpekKategoritBangunan::class,
        'spek-bangunan' => SpekBangunan::class,
        'lantai-unit' => Lantai::class,
        'view-unit' => ViewUnit::class,
        'jenis-pesawat' => JenisPesawat::class,
        'model-alat-berat' => ModelAlatBerat::class,
        'jenis-kapal' => JenisKapal::class,
        'jenis-kendaraan' => JenisKendaraan::class,
        'terletak-area' => TerletakArea::class,
        'posisi-unit' => PosisiUnit::class,
        'bentuk-unit' => BentukUnit::class,
        'fasilitas-objek' => FasilitasObjek::class,
        'merupakan-daerah' => MerupakanDaerah::class,
        'jenis-unit' => JenisUnit::class,
        'perkerasan-jalan' => PerkerasanJalan::class,
        'foto-objek-jaminan' => FotoObjekJaminan::class,
        'perizinan' => Perizinan::class
    ];




    public function getCommonData()
    {
        return [
            'branches' => Branch::all(),
            'bentukTanah' => BentukTanah::all(),
            'konturTanah' => KonturTanah::all(),
            'posisiKavling' => PosisiKavling::all(),
            'ketinggianTanah' => KetinggianTanah::all(),
            'kondisiFisikTanah' => KondisiFisikTanah::all(),
            'jenisBangunan' => JenisBangunan::all(),
            'kondisiBangunan' => KondisiBangunan::all(),
            'sifatBangunan' => SifatBangunan::all(),
            'spekKategoriBangunan' => SpekKategoritBangunan::all(),
            'spekBangunan' => SpekBangunan::all(),
            'saranaPelengkap' => SaranaPelengkap::all(),
            'arahMataAngin' => ArahMataAngin::all(),
            'lantai' => Lantai::all(),
            'viewUnit' => ViewUnit::all(),
            'golMasySekitar' => GolonganMasySekitar::all(),
            'tingkatKeramaian' => TingkatKeramaian::all(),
            'laluLintasLokasi' => LaluLintasLokasi::all(),
            'jenisPesawat' => JenisPesawat::all(),
            'modelAlatBerat' => ModelAlatBerat::all(),
            'jenisKapal' => JenisKapal::all(),
            'jenisKendaraan' => JenisKendaraan::all(),
            'terletakArea' => TerletakArea::all(),
            'posisiUnit' => PosisiUnit::all(),
            'bentukUnit' => BentukUnit::all(),
            'fasilitasObjek' => FasilitasObjek::all(),
            'merupakanDaerah' => MerupakanDaerah::all(),
            'jenisUnit' => JenisUnit::all(),
            'jenisJaminan' => JenisJaminan::all(),
            'hubCadeb' => HubunganPemilikJaminan::all(),
            'hubPenghuni' => HubunganPenghuniJaminan::all(),
            'perkerasanJalan' => PerkerasanJalan::all(),
            'terletakDiArea' => TerletakArea::all(),
            'tujuanPenilaian' => TujuanPenilaian::all(),
            'perizinan' => Perizinan::all(),
            'foto' =>  FotoObjekJaminan::all()
        ];
    }

    private const HEADERS = [
        'bentuk-tanah' => ['Bentuk Tanah', 'bentuk-tanah'],
        'kontur-tanah' => ['Kontur Tanah', 'kontur-tanah'],
        'posisi-kavling' => ['Posisi Kavling', 'posisi-kavling'],
        'ketinggian-tanah' => ['Ketinggian Tanah', 'ketinggian-tanah'],
        'kondisi-fisik-tanah' => ['Kondisi Fisik Tanah', 'kondisi-fisik-tanah'],
        'jenis-bangunan' => ['Jenis Bangunan', 'jenis-bangunan'],
        'kondisi-bangunan' => ['Kondisi Bangunan', 'kondisi-bangunan'],
        'sifat-bangunan' => ['Sifat Bangunan', 'sifat-bangunan'],
        'sarana-pelengkap' => ['Sarana Pelengkap', 'sarana-pelengkap'],
        'lalu-lintas-lokasi' => ['Lalu Lintas Depan Lokasi', 'lalu-lintas-lokasi'],
        'tingkat-keramaian' => ['Tingkat Keramaian', 'tingkat-keramaian'],
        'gol-mas-sekitar' => ['Golongan Masyarakat Sekitar', 'gol-mas-sekitar'],
        'spek-kategori-bangunan' => ['Spek Kategori Bangunan', 'spek-kategori-bangunan'],
        'spek-bangunan' => ['Spek Bangunan', 'spek-bangunan'],
        'lantai-unit' => ['Lantai Unit', 'lantai-unit'],
        'view-unit' => ['View Unit', 'view-unit'],
        'perkerasan-jalan' => ['Perkerasan jalan', 'perkerasan-jalan'],
        'jenis-pesawat' => ['Jenis pesawat', 'jenis-pesawat'],
        'model-alat-berat' => ['Model alat berat', 'model-alat-berat'],
        'jenis-kapal' => ['Jenis kapal', 'jenis-kapal'],
        'jenis-kendaraan' => ['Jenis kendaraan', 'jenis-kendaraan'],
        'jenis-unit' => ['Jenis unit', 'jenis-unit'],
        'terletak-area' => ['Terletak di Area', 'terletak-area'],
        'merupakan-daerah' => ['Merupakan Daerah', 'merupakan-daerah'],
        'posisi-unit' => ['Posisi unit', 'posisi-unit'],
        'bentuk-unit' => ['Bentuk unit', 'bentuk-unit'],
        'fasilitas-objek' => ['Fasilitas Umum Dekat Objek', 'fasilitas-objek'],
        'foto-objek-jaminan' => ['Foto Objek Jaminan', 'foto-objek-jaminan'],
        'perizinan' => ['Perizinan', 'perizinan'],
    ];




    private function updateOrDeleteFile($data, $request, $fileKey)
    {
        if ($request->hasFile($fileKey)) {
            $file = $request->file($fileKey);
            if ($file->isValid()) {
                $fileName = time() . '_' . $file->getClientOriginalName();
                $path = $file->storeAs("public/surveyor/{$request->type}", $fileName);

                if ($path === false) {
                    throw new \Exception("Failed to store file for {$fileKey}");
                }
                if (isset($data[$fileKey]) && $data[$fileKey]) {
                    $this->deleteFile($data[$fileKey]);
                }
                return str_replace('public/', '', $path);
            } else {
                throw new \Exception("Invalid file upload for {$fileKey}");
            }
        } elseif (isset($data[$fileKey]) && $data[$fileKey]) {
            return $data[$fileKey];
        } else {
            return null;
        }
    }

    private function deleteFile($filePath)
    {
        $fullPath = storage_path('app/public/' . $filePath);
        if (file_exists($fullPath)) {
            unlink($fullPath);
        }
    }

    /**
     * Helper untuk upload file
     *
     * @param $file
     * @param $type
     * @return path name
     */


    public function uploadFile($file, $type)
    {
        if (!$file->isValid()) {
            throw new \Exception("Invalid file upload for {$type}");
        }

        $fileName = time() . '_' . $file->getClientOriginalName();
        $path = $file->storeAs("public/surveyor/{$type}", $fileName);

        if ($path === false) {
            throw new \Exception("Failed to store file for {$type}");
        }

        return str_replace('public/', '', $path);
    }

    /**
     * Helper untuk memetakan array dengan inputannya
     *
     * @param array $keys Array kunci
     * @param array $values Array nilai/input
     * @return array
     */
    private function mapArrayWithInputs(array $keys, array $values): array
    {
        $result = [];

        foreach ($keys as $key) {
            // Jika checkbox dicentang, ambil nilai input yang sesuai
            // Gunakan nilai dari $values berdasarkan nama checkbox
            $result[$key] = $values[$key] ?? null;
        }

        return $result;
    }


    public function export(string $type)
    {
        $modelClass = $this->getModelClass($type);

        if (!$modelClass) {

            return response()->json([
                'message' => 'Invalid type provided.',
                'available_types' => array_keys($this->modelClasses),
            ], 400);
        }

        // Return Excel download
        return Excel::download(new BasicDataSurveyorExport($modelClass), $type . '.xlsx');
    }


    public function signatureStore(Request $request)
    {

        $validator = Validator::make($request->all(), [
            'signature' => 'required',
            'type' => 'required|in:penilai,cabang,debitur,kjpp',
            'name' => 'nullable|string',
            'document_id' => 'nullable|string'
        ]);

        if ($validator->fails()) {
            return response()->json([
                'success' => false,
                'message' => $validator->errors()->first()
            ], 422);
        }

        try {

            $inspeksi = Inspeksi::where('permohonan_id', $request->input('permohonan_id'))
                ->where('dokument_id', $request->input('document_id'))
                ->first();

            if (!$inspeksi) {
                $inspeksi = new Inspeksi();
                $inspeksi->permohonan_id = $request->input('permohonan_id');
                $inspeksi->dokument_id = $request->input('document_id');
                $inspeksi->data_form = json_encode([]); // Inisialisasi data_form kosong
                $inspeksi->save();
            }

            // Decode data form yang ada
            $dataForm = json_decode($inspeksi->data_form, true) ?: [];

            // Inisialisasi array signature jika belum ada
            if (!isset($dataForm['signature'])) {
                $dataForm['signature'] = [];
            }

            // Simpan atau update signature berdasarkan type
            $dataForm['signature'][$request->type] = [
                'image' => $request->signature,
                'name' => $request->name,
                'created_at' => now()->toDateTimeString(),
                'updated_at' => now()->toDateTimeString()
            ];

            // Update data form di database
            $inspeksi->data_form = json_encode($dataForm);
            $inspeksi->save();

            return response()->json([
                'success' => true,
                'message' => 'Tanda tangan berhasil disimpan'
            ]);

        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Terjadi kesalahan: ' . $e->getMessage()
            ], 500);
        }
    }
    public function signatureShow($type)
    {
        try {
            $inspeksi = Inspeksi::where('permohonan_id', request()->input('permohonan_id'))
                ->where('dokument_id', request()->input('document_id'))
                ->first();

            if (!$inspeksi) {
                return response()->json([
                    'success' => false,
                    'message' => 'Data inspeksi tidak ditemukan',
                    'error_code' => '404'
                ], 404);
            }

            $dataForm = json_decode($inspeksi->data_form, true) ?: [];

            if (isset($dataForm['signature'][$type])) {
                return response()->json([
                    'success' => true,
                    'data' => [
                        'signature' => $dataForm['signature'][$type]['image'],
                        'type' => $type,
                        'name' => $dataForm['signature'][$type]['name'] ?? '',
                        'created_at' => $dataForm['signature'][$type]['created_at'],
                        'updated_at' => $dataForm['signature'][$type]['updated_at']
                    ]
                ]);
            }

            return response()->json([
                'success' => false,
                'message' => 'Tanda tangan tidak ditemukan',
                'error_code' => '404'
            ], 404);

        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Terjadi kesalahan: ' . $e->getMessage(),
                'error_code' => '500'
            ], 500);
        }
    }

    public function signatureDestroy(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'type' => 'required|in:penilai,cabang,debitur,kjpp'
            ]);

            if ($validator->fails()) {
                return response()->json([
                    'success' => false,
                    'message' => 'Validation error',
                    'errors' => $validator->errors()
                ], 422);
            }

            $inspeksi = Inspeksi::where('permohonan_id', $request->input('permohonan_id'))
                ->where('dokument_id', $request->input('document_id'))
                ->first();

            if (!$inspeksi) {
                return response()->json([
                    'success' => false,
                    'message' => 'Data inspeksi tidak ditemukan',
                    'error_code' => '404'
                ], 404);
            }

            $dataForm = json_decode($inspeksi->data_form, true) ?: [];

            if (isset($dataForm['signature'][$request->type])) {
                unset($dataForm['signature'][$request->type]);

                $inspeksi->data_form = json_encode($dataForm);
                $inspeksi->save();

                return response()->json([
                    'success' => true,
                    'message' => 'Tanda tangan berhasil dihapus',
                    'data' => [
                        'type' => $request->type,
                        'deleted_at' => now()->toDateTimeString()
                    ]
                ]);
            }

            return response()->json([
                'success' => false,
                'message' => 'Tanda tangan tidak ditemukan',
                'error_code' => '404'
            ], 404);

        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Terjadi kesalahan: ' . $e->getMessage(),
                'error_code' => '500'
            ], 500);
        }
    }




    public function print_out_inspeksi($permohonan_id, $dokument_id, $jenis_jaminan_id)
    {
        // Ambil data permohonan dan data umum
        $permohonan = $this->getPermohonanJaminanId($permohonan_id, $dokument_id, $jenis_jaminan_id);
        $basicData = $this->getCommonData();

        // Ambil data inspeksi
        $inspeksi = Inspeksi::where('permohonan_id', $permohonan_id)
            ->where('dokument_id', $dokument_id)
            ->first();

        if (!$inspeksi) {
            // Redirect jika inspeksi tidak ditemukan
            return redirect()->back()->with('error', 'Data inspeksi tidak ditemukan.');
        }

        $forminspeksi = json_decode($inspeksi->data_form, true);

        if (!$forminspeksi) {
            // Redirect jika data form inspeksi kosong
            return redirect()->back()->with('error', 'Silahkan isi terlebih dahulu form inspeksi.');
        }


        $inputAddress = $forminspeksi['asset']['alamat']['sesuai'] ?? $forminspeksi['asset']['alamat']['tidak sesuai'] ?? [];

        $alamat = [
            'address' => $inputAddress['address'] ?? null,
            'village_code' => getWilayahName($inputAddress['village_code'] ?? null, 'village'),
            'district_code' => getWilayahName($inputAddress['district_code'] ?? null, 'district'),
            'city_code' => getWilayahName($inputAddress['city_code'] ?? null, 'city'),
            'province_code' => getWilayahName($inputAddress['province_code'] ?? null, 'province')
        ];


        // Decode data form inspeksi
        $forminspeksi = json_decode($inspeksi->data_form, true);

        if (!$forminspeksi) {
            // Redirect jika data form inspeksi kosong
            return redirect()->back()->with('error', 'Silahkan isi terlebih dahulu form inspeksi.');
        }

        $templateView = '';
        switch (strtolower($inspeksi->name)) {
            case 'rap':
                $templateView = 'lpj::surveyor.components.print-out.main';
                break;
            case 'mesin':
                $templateView = 'lpj::surveyor.components.print-out.mesin';
                break;
            case 'kendaraan':
                $templateView = 'lpj::surveyor.components.print-out.kendaraan';
                break;
            case 'pesawat':
                $templateView = 'lpj::surveyor.components.print-out.pesawat';
                break;
            case 'alat-berat':
                $templateView = 'lpj::surveyor.components.print-out.alat-berat';
                break;
            default:
                $templateView = 'lpj::surveyor.components.print-out.main';
                break;
        }

        // Generate PDF
        $pdf = PDF::loadView($templateView, compact('permohonan', 'basicData', 'forminspeksi', 'alamat'));

        // Tentukan nama file PDF
        $namaDebiture = $permohonan->debiture->name . '-' . $permohonan->nomor_registrasi;
        $fileName = 'inspeksi-' . $namaDebiture . '-data.pdf';
        $pdf->set_option('isHtml5ParserEnabled', true);
        $pdf->set_option('isPhpEnabled', true);
        return $pdf->stream($fileName);
    }

    public function approveReschedule(Request $request, $id)
    {
        try {
            // Validasi data yang diterima
            $validatedData = $request->validate([
                'permohonan_id' => 'required|exists:permohonan,id',
                'nomor_registrasi' => 'required'
            ]);

            // Memulai transaksi
            DB::beginTransaction();

            // Update status permohonan menjadi "reschedule"
            $permohonan = Permohonan::findOrFail($validatedData['permohonan_id']);
            $permohonan->update([
                'status' => 'approved-reschedule',
            ]);

            // Update data penilaian dengan waktu reschedule
            $penilaian = Penilaian::findOrFail($id);
            $penilaian->update([
                'waktu_penilaian' => $penilaian->reschedule_date,
            ]);

            // Commit transaksi
            DB::commit();

            return response()->json([
                'status' => 'success',
                'message' => 'Reschedule jadwal dengan nomor registrasi ' . $validatedData['nomor_registrasi'] . ' berhasil disetujui.',
            ]);
        } catch (\Exception $e) {
            // Rollback jika ada error
            DB::rollBack();
            return response()->json([
                'status' => 'error',
                'message' => 'Gagal menyetujui reschedule: ' . $e->getMessage(),
            ], 500);
        }
    }

    /**
     * Reject reschedule request.
     */
    public function rejectReschedule(Request $request, $id)
    {
        try {
            // Validasi data yang diterima
            $validatedData = $request->validate([
                'permohonan_id' => 'required|exists:permohonan,id',
                'rejected_note' => 'required|string|max:255',
                'nomor_registrasi' => 'required|string',
                'keterangan' => 'required|string',
            ]);

            // Memulai transaksi
            DB::beginTransaction();

            // Update status permohonan menjadi "rejected-reschedule"
            $permohonan = Permohonan::findOrFail($validatedData['permohonan_id']);
            $permohonan->update([
                'status' => 'rejected-reschedule',
            ]);

            // Update data penilaian dengan catatan penolakan
            $penilaian = Penilaian::findOrFail($id);
            $penilaian->update([
                'rejected_note' => $validatedData['rejected_note'],
            ]);

            // Commit transaksi
            DB::commit();

            return response()->json([
                'status' => 'success',
                'message' => 'Reschedule jadwal dengan nomor registrasi ' . $validatedData['nomor_registrasi'] . ' berhasil dengan alasan: ' . $validatedData['rejected_note'],
            ]);
        } catch (\Exception $e) {
            // Rollback jika ada error
            DB::rollBack();
            return response()->json([
                'status' => 'error',
                'message' => 'Gagal menolak reschedule: ' . $e->getMessage(),
            ], 500);
        }
    }

    public function storeProsesSurvey(Request $request, $id)
    {
        try {

            $validated = $request->validate([
                'permohonan_id' => 'required|integer|exists:permohonan,id',
            ]);


            $permohonan = Permohonan::findOrFail($id);

            $permohonan->status = 'survey';
            $permohonan->save();

            // Berikan respons JSON
            return response()->json([
                'status' => 'success',
                'message' => 'Status permohonan berhasil diubah menjadi "survey".',
            ]);
        } catch (\Exception $e) {
            // Tangani error
            return response()->json([
                'status' => 'error',
                'message' => $e->getMessage(),
            ], 500);
        }
    }

    public function uploadFileFoto(Request $request, $url)
    {

        // dd($request->all());
        $inspeksi = Inspeksi::where('permohonan_id', $request->input('permohonan_id'))
            ->where('dokument_id', $request->input('dokument_id'))
            ->first();

        $fotoTypes = [
            'foto_gistaru',
            'foto_bhumi',
            'foto_argis_region',
            'foto_tempat',
            'foto_sentuh_tanahku',
            'upload_gs'
        ];

        if (!in_array($url, $fotoTypes)) {
            return response()->json([
                'success' => false,
                'message' => 'Invalid key for upload'
            ], 400);
        }


        $existingData = $inspeksi ? json_decode($inspeksi->data_form, true) : [];
        $existingData = $existingData ?? [];


        $factData = $existingData;
        if ($request->hasFile('file')) {
            $file = $request->file('file');
            $filePath = $file->store('uploads', 'public');
            $uploadedPath = str_replace('public/', '', $filePath);


            $factData[$url] = $uploadedPath;


            $existingData = $factData;
            if ($inspeksi) {
                $inspeksi->data_form = json_encode($existingData);
                $inspeksi->save();
            } else {
                Inspeksi::updateOrCreate([
                    'permohonan_id' => $request->input('permohonan_id'),
                    'dokument_id' => $request->input('document_id')
                ],[
                    'data_form' => json_encode($existingData),
                ]);
            }
        } else {
            return response()->json([
                'success' => false,
                'message' => 'No file uploaded for the given key'
            ], 400);
        }

        return response()->json([
            'success' => true,
            'message' => 'Berhasil upload file foto',
            'data' => [
                'key' => $url,
                'path' => $factData[$url] ?? null
            ]
        ]);
    }

    /**
     * Fungsi untuk cleanup data inspeksi otomatis
     * Menghapus data inspeksi tanpa dokument_id jika ada data lain dengan dokument_id yang sama
     */
    private function cleanupInspeksiData($permohonanId)
    {
        try {
            Log::info('SurveyorController: Memulai cleanup inspeksi otomatis', [
                'permohonan_id' => $permohonanId,
                'user_id' => Auth::id()
            ]);

            // Ambil data inspeksi yang memiliki dokument_id (data lengkap)
            $dataWithDokument = Inspeksi::where('permohonan_id', $permohonanId)
                ->whereNotNull('dokument_id')
                ->whereNull('deleted_at')
                ->get();

            // Ambil data inspeksi yang tidak memiliki dokument_id (data yang akan di-cleanup)
            $dataWithoutDokument = Inspeksi::where('permohonan_id', $permohonanId)
                ->whereNull('dokument_id')
                ->whereNull('deleted_at')
                ->get();

            // Jika ada data tanpa dokument_id, cek apakah ada data dengan dokument_id yang sama
            if ($dataWithoutDokument->isNotEmpty() && $dataWithDokument->isNotEmpty()) {
                
                // Group data dengan dokument_id by created_by
                $groupedDataWithDokument = $dataWithDokument->groupBy('created_by');
                
                // Group data tanpa dokument_id by created_by
                $groupedDataWithoutDokument = $dataWithoutDokument->groupBy('created_by');

                // Proses cleanup untuk setiap user
                foreach ($groupedDataWithDokument as $userId => $userDataWithDokument) {
                    
                    // Cek apakah user ini juga memiliki data tanpa dokument_id
                    if (isset($groupedDataWithoutDokument[$userId])) {
                        
                        // Ambil salah satu data dengan dokument_id sebagai referensi untuk logging
                        $referenceData = $userDataWithDokument->first();
                        
                        Log::info('SurveyorController: Menemukan data lengkap untuk user, akan menghapus data tidak lengkap', [
                            'user_id' => $userId,
                            'permohonan_id' => $permohonanId,
                            'reference_dokument_id' => $referenceData->dokument_id,
                            'data_count_to_delete' => $groupedDataWithoutDokument[$userId]->count()
                        ]);
                        
                        // Ambil semua data tanpa dokument_id untuk user ini
                        $userDataWithoutDokument = $groupedDataWithoutDokument[$userId];

                        // Soft delete data tanpa dokument_id
                        foreach ($userDataWithoutDokument as $dataToDelete) {
                            DB::beginTransaction();
                            try {
                                // Soft delete data
                                $dataToDelete->delete();
                                
                                Log::info('SurveyorController: Data inspeksi berhasil di-soft delete', [
                                    'id' => $dataToDelete->id,
                                    'permohonan_id' => $dataToDelete->permohonan_id,
                                    'dokument_id' => $dataToDelete->dokument_id,
                                    'created_by' => $dataToDelete->created_by,
                                    'deleted_at' => now()
                                ]);

                                DB::commit();
                            } catch (\Exception $e) {
                                DB::rollback();
                                Log::error('SurveyorController: Gagal menghapus data inspeksi', [
                                    'id' => $dataToDelete->id,
                                    'error' => $e->getMessage()
                                ]);
                            }
                        }
                    }
                }
            }

            Log::info('SurveyorController: Cleanup inspeksi otomatis selesai', [
                'permohonan_id' => $permohonanId,
                'data_with_dokument' => $dataWithDokument->count(),
                'data_without_dokument' => $dataWithoutDokument->count()
            ]);

        } catch (\Exception $e) {
            Log::error('SurveyorController: Error saat cleanup inspeksi otomatis', [
                'permohonan_id' => $permohonanId,
                'error' => $e->getMessage(),
                'trace' => $e->getTraceAsString()
            ]);
        }
    }

}
