<?php

namespace App\Http\Controllers;

use App\Models\Mahasiswa;
use App\Models\Kampus;
use App\Models\Prodi;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Log;

class PengajuanStatusController extends Controller
{
    /**
     * Halaman utama pengajuan
     */
    public function index(Request $request)
    {
        $user = Auth::user();
        $isGlobal = $user->role->name === 'superadmin' || $user->role->name === 'admin';

        $query = Mahasiswa::with(['kampus', 'prodi', 'pengaju'])
            ->orderBy('created_at', 'desc');

        if (!$isGlobal && $user->kampus_id) {
            $query->where('kampus_id', $user->kampus_id);
        } elseif ($request->kampus_id && $request->kampus_id !== '' && $request->kampus_id !== 'all') {
            $query->where('kampus_id', $request->kampus_id);
        }

        if ($request->prodi_id && $request->prodi_id !== '' && $request->prodi_id !== 'all') {
            $query->where('prodi_id', $request->prodi_id);
        }

        if ($request->status_akademik && $request->status_akademik !== '' && $request->status_akademik !== 'all') {
            $query->where('status_akademik', $request->status_akademik);
        }

        if ($request->pengajuan_status && $request->pengajuan_status !== '' && $request->pengajuan_status !== 'all') {
            $query->where('pengajuan_status', $request->pengajuan_status);
        }

        if ($request->search && $request->search !== '') {
            $query->where(function ($q) use ($request) {
                $q->where('nama', 'like', "%{$request->search}%")
                    ->orWhere('nim', 'like', "%{$request->search}%");
            });
        }

        $mahasiswa = $query->paginate(10)->withQueryString();

        $kampusList = $isGlobal ? Kampus::select('id', 'nama', 'singkatan')->get() : collect([]);
        $prodiList = collect([]);

        if ($request->kampus_id && $request->kampus_id !== '' && $request->kampus_id !== 'all') {
            $prodiList = Prodi::where('kampus_id', $request->kampus_id)
                ->select('id', 'nama', 'kode', 'jenjang')
                ->get();
        }

        return view('pengajuan-status.index', compact('mahasiswa', 'kampusList', 'prodiList'));
    }

    /**
     * STORE SINGLE PENGAJUAN
     */
    public function store(Request $request)
    {
        $rules = [
            'mahasiswa_id' => 'required|exists:mahasiswa,id',
            'pengajuan_jenis' => 'required|in:aktif,cuti,drop_out,lulus,tidak_aktif',
            'pengajuan_file' => 'nullable|file|mimes:pdf,jpg,jpeg,png|max:2048',
            'bukti_bayar_file' => 'nullable|file|mimes:pdf,jpg,jpeg,png|max:2048',
        ];

        if ($request->pengajuan_jenis === 'cuti') {
            $rules['cuti_semester'] = 'required|integer|min:1|max:14';
        }

        $request->validate($rules);

        DB::beginTransaction();
        try {
            $mahasiswa = Mahasiswa::findOrFail($request->mahasiswa_id);

            if ($mahasiswa->pengajuan_status === 'pending') {
                return redirect()->back()
                    ->with('error', "Mahasiswa {$mahasiswa->nama} sudah memiliki pengajuan pending.");
            }

            if ($mahasiswa->status_akademik === $request->pengajuan_jenis) {
                return redirect()->back()
                    ->with('error', "Status yang diajukan sama dengan status saat ini.");
            }

            $data = [
                'pengajuan_jenis' => $request->pengajuan_jenis,
                'pengajuan_status' => 'pending',
                'pengajuan_at' => now(),
                'pengajuan_by' => Auth::id(),
                'pengajuan_validasi_at' => null,
                'pengajuan_validasi_by' => null,
            ];

            // UNTUK CUTI: JANGAN SIMPAN cuti_semester DULU!
            // Simpan semester cuti di variabel sementara untuk digunakan saat approve
            // Kita simpan di atribut model atau session
            if ($request->pengajuan_jenis === 'cuti') {
                // Simpan semester cuti di session atau property sementara
                session(['pending_cuti_semester_' . $mahasiswa->id => (int) $request->cuti_semester]);
            }

            // Upload file pengajuan jika ada
            if ($request->hasFile('pengajuan_file')) {
                if ($mahasiswa->pengajuan_file) {
                    Storage::disk('public')->delete($mahasiswa->pengajuan_file);
                }
                $path = $request->file('pengajuan_file')->store('pengajuan/' . $mahasiswa->nim, 'public');
                $data['pengajuan_file'] = $path;
            }

            // Upload bukti bayar jika ada
            if ($request->hasFile('bukti_bayar_file')) {
                if ($mahasiswa->bukti_bayar_file) {
                    Storage::disk('public')->delete($mahasiswa->bukti_bayar_file);
                }
                $path = $request->file('bukti_bayar_file')->store('bukti-bayar/' . $mahasiswa->nim, 'public');
                $data['bukti_bayar_file'] = $path;
            }

            $mahasiswa->update($data);

            DB::commit();

            return redirect()->route('pengajuan-status.index')
                ->with('success', "Pengajuan untuk {$mahasiswa->nama} berhasil dibuat.");

        } catch (\Exception $e) {
            DB::rollBack();
            Log::error('Gagal membuat pengajuan: ' . $e->getMessage());
            return redirect()->back()
                ->with('error', 'Terjadi kesalahan: ' . $e->getMessage())
                ->withInput();
        }
    }

    /**
     * BULK CREATE PENGAJUAN
     */
    public function bulkStore(Request $request)
    {
        $rules = [
            'mahasiswa_ids' => 'required|string',
            'pengajuan_jenis' => 'required|in:aktif,cuti,drop_out,lulus,tidak_aktif',
            'pengajuan_file' => 'nullable|file|mimes:pdf,jpg,jpeg,png|max:2048',
            'bukti_bayar_file' => 'nullable|file|mimes:pdf,jpg,jpeg,png|max:2048',
        ];

        if ($request->pengajuan_jenis === 'cuti') {
            $rules['cuti_semester'] = 'required|integer|min:1|max:14';
        }

        $request->validate($rules);

        $mahasiswaIds = json_decode($request->mahasiswa_ids, true);

        if (!is_array($mahasiswaIds) || count($mahasiswaIds) === 0) {
            return redirect()->back()
                ->with('error', 'Pilih minimal 1 mahasiswa.')
                ->withInput();
        }

        DB::beginTransaction();
        try {
            $successCount = 0;
            $skippedCount = 0;
            $errors = [];

            $globalPengajuanFile = null;
            $globalBuktiBayarFile = null;

            if ($request->hasFile('pengajuan_file')) {
                $globalPengajuanFile = $request->file('pengajuan_file');
            }
            if ($request->hasFile('bukti_bayar_file')) {
                $globalBuktiBayarFile = $request->file('bukti_bayar_file');
            }

            // Untuk bulk cuti, simpan semester cuti ke session untuk setiap mahasiswa
            $cutiSemester = $request->pengajuan_jenis === 'cuti' ? (int) $request->cuti_semester : null;

            foreach ($mahasiswaIds as $mahasiswaId) {
                $mahasiswa = Mahasiswa::find($mahasiswaId);

                if (!$mahasiswa) {
                    $skippedCount++;
                    $errors[] = "Mahasiswa dengan ID {$mahasiswaId} tidak ditemukan";
                    continue;
                }

                if ($mahasiswa->pengajuan_status === 'pending') {
                    $skippedCount++;
                    $errors[] = "{$mahasiswa->nama} (NIM: {$mahasiswa->nim}) - sudah memiliki pengajuan pending";
                    continue;
                }

                if ($mahasiswa->status_akademik === $request->pengajuan_jenis) {
                    $skippedCount++;
                    $errors[] = "{$mahasiswa->nama} (NIM: {$mahasiswa->nim}) - status yang diajukan sama dengan status saat ini";
                    continue;
                }

                $data = [
                    'pengajuan_jenis' => $request->pengajuan_jenis,
                    'pengajuan_status' => 'pending',
                    'pengajuan_at' => now(),
                    'pengajuan_by' => Auth::id(),
                    'pengajuan_validasi_at' => null,
                    'pengajuan_validasi_by' => null,
                ];

                // UNTUK CUTI: JANGAN SIMPAN cuti_semester DULU!
                // Simpan semester cuti di session untuk digunakan saat approve
                if ($request->pengajuan_jenis === 'cuti' && $cutiSemester) {
                    session(['pending_cuti_semester_' . $mahasiswa->id => $cutiSemester]);
                }

                // Handle file upload untuk cuti
                if ($request->pengajuan_jenis === 'cuti') {
                    if ($globalPengajuanFile) {
                        if ($mahasiswa->pengajuan_file) {
                            Storage::disk('public')->delete($mahasiswa->pengajuan_file);
                        }
                        $extension = $globalPengajuanFile->getClientOriginalExtension();
                        $fileName = 'pengajuan_' . $mahasiswa->nim . '_' . time() . '.' . $extension;
                        $path = $globalPengajuanFile->storeAs('pengajuan/' . $mahasiswa->nim, $fileName, 'public');
                        $data['pengajuan_file'] = $path;
                    }

                    if ($globalBuktiBayarFile) {
                        if ($mahasiswa->bukti_bayar_file) {
                            Storage::disk('public')->delete($mahasiswa->bukti_bayar_file);
                        }
                        $extension = $globalBuktiBayarFile->getClientOriginalExtension();
                        $fileName = 'bukti_' . $mahasiswa->nim . '_' . time() . '.' . $extension;
                        $path = $globalBuktiBayarFile->storeAs('bukti-bayar/' . $mahasiswa->nim, $fileName, 'public');
                        $data['bukti_bayar_file'] = $path;
                    }
                }

                $mahasiswa->update($data);
                $successCount++;
            }

            DB::commit();

            $message = "Berhasil membuat {$successCount} pengajuan.";
            if ($skippedCount > 0) {
                $message .= " {$skippedCount} mahasiswa dilewati.";
            }

            if (!empty($errors)) {
                return redirect()->route('pengajuan-status.index')
                    ->with('warning', $message)
                    ->with('bulk_errors', $errors);
            }

            return redirect()->route('pengajuan-status.index')
                ->with('success', $message);

        } catch (\Exception $e) {
            DB::rollBack();
            Log::error('Gagal bulk create pengajuan: ' . $e->getMessage());
            return redirect()->back()
                ->with('error', 'Terjadi kesalahan: ' . $e->getMessage())
                ->withInput();
        }
    }

    /**
     * Download file pengajuan
     */
    public function downloadPengajuanFile($id)
    {
        $mahasiswa = Mahasiswa::findOrFail($id);

        if (!$mahasiswa->pengajuan_file) {
            return redirect()->back()->with('error', 'File pengajuan tidak ditemukan.');
        }

        if (!Storage::disk('public')->exists($mahasiswa->pengajuan_file)) {
            return redirect()->back()->with('error', 'File pengajuan tidak ditemukan di storage.');
        }

        $path = Storage::disk('public')->path($mahasiswa->pengajuan_file);
        $extension = pathinfo($path, PATHINFO_EXTENSION);
        $fileName = 'pengajuan_' . $mahasiswa->nim . '_' . $mahasiswa->nama . '.' . $extension;

        return response()->download($path, $fileName);
    }

    /**
     * Download bukti bayar
     */
    public function downloadBuktiBayarFile($id)
    {
        $mahasiswa = Mahasiswa::findOrFail($id);

        if (!$mahasiswa->bukti_bayar_file) {
            return redirect()->back()->with('error', 'Bukti bayar tidak ditemukan.');
        }

        if (!Storage::disk('public')->exists($mahasiswa->bukti_bayar_file)) {
            return redirect()->back()->with('error', 'Bukti bayar tidak ditemukan di storage.');
        }

        $path = Storage::disk('public')->path($mahasiswa->bukti_bayar_file);
        $extension = pathinfo($path, PATHINFO_EXTENSION);
        $fileName = 'bukti_bayar_' . $mahasiswa->nim . '_' . $mahasiswa->nama . '.' . $extension;

        return response()->download($path, $fileName);
    }

    /**
     * Search mahasiswa untuk dipilih (AJAX)
     */
    public function searchMahasiswa(Request $request)
    {
        $request->validate([
            'search' => 'required|string|min:2',
        ]);

        $user = Auth::user();
        $isGlobal = $user->role->name === 'superadmin' || $user->role->name === 'admin';

        $query = Mahasiswa::with(['kampus', 'prodi'])
            ->where(function ($q) use ($request) {
                $q->where('nama', 'like', "%{$request->search}%")
                    ->orWhere('nim', 'like', "%{$request->search}%");
            });

        if (!$isGlobal && $user->kampus_id) {
            $query->where('kampus_id', $user->kampus_id);
        }

        $mahasiswa = $query->limit(20)->get();

        return response()->json($mahasiswa);
    }

    /**
     * Detail mahasiswa (AJAX)
     */
    public function show($id)
    {
        try {

            $mahasiswa = Mahasiswa::with(['kampus', 'prodi', 'pengaju', 'validatorPengajuan'])
                ->findOrFail($id);

            // Proses cuti_semester
            $cutiSemester = $mahasiswa->cuti_semester;
            $cutiHistoryText = '-';

            if (!is_null($cutiSemester)) {
                if (is_string($cutiSemester) && str_starts_with($cutiSemester, '[')) {
                    $cutiSemester = json_decode($cutiSemester, true);
                }
                if (is_array($cutiSemester) && count($cutiSemester) > 0) {
                    $cutiHistoryText = 'Semester ' . implode(', ', $cutiSemester);
                } elseif (!is_array($cutiSemester) && $cutiSemester != '') {
                    $cutiHistoryText = 'Semester ' . $cutiSemester;
                }
            }

            $responseData = [
                'id' => $mahasiswa->id,
                'nim' => $mahasiswa->nim ?? '-',
                'nama' => $mahasiswa->nama ?? '-',
                'kampus' => $mahasiswa->kampus->nama ?? '-',
                'prodi' => $mahasiswa->prodi->nama ?? '-',
                'angkatan' => $mahasiswa->angkatan ?? '-',
                'status_akademik' => $mahasiswa->status_akademik,
                'status_akademik_text' => $this->getStatusText($mahasiswa->status_akademik),
                'pengajuan_jenis' => $mahasiswa->pengajuan_jenis,
                'pengajuan_jenis_text' => $this->getStatusText($mahasiswa->pengajuan_jenis),
                'pengajuan_status' => $mahasiswa->pengajuan_status,
                'pengajuan_status_text' => $this->getPengajuanStatusText($mahasiswa->pengajuan_status),
                'pengajuan_at' => $mahasiswa->pengajuan_at ? $mahasiswa->pengajuan_at->format('d/m/Y H:i') : null,
                'pengajuan_by' => $mahasiswa->pengaju->name ?? '-',
                'pengajuan_file' => $mahasiswa->pengajuan_file,
                'pengajuan_file_url' => $mahasiswa->pengajuan_file ? asset('storage/' . $mahasiswa->pengajuan_file) : null,
                'bukti_bayar_file' => $mahasiswa->bukti_bayar_file,
                'bukti_bayar_file_url' => $mahasiswa->bukti_bayar_file ? asset('storage/' . $mahasiswa->bukti_bayar_file) : null,
                'cuti_semester' => $cutiSemester,
                'cuti_history_text' => $cutiHistoryText,
                'pengajuan_validasi_at' => $mahasiswa->pengajuan_validasi_at ? $mahasiswa->pengajuan_validasi_at->format('d/m/Y H:i') : null,
                'validator' => $mahasiswa->validatorPengajuan->name ?? '-',
            ];

            return response()->json($responseData);

        } catch (\Illuminate\Database\Eloquent\ModelNotFoundException $e) {
            return response()->json([
                'error' => true,
                'message' => 'Data mahasiswa tidak ditemukan'
            ], 404);

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

    /**
     * Get prodi by kampus for AJAX
     */
    public function getProdiByKampus($kampusId)
    {
        if ($kampusId === 'all' || $kampusId === '') {
            return response()->json([]);
        }

        $prodi = Prodi::where('kampus_id', $kampusId)
            ->select('id', 'nama', 'kode', 'jenjang')
            ->orderBy('nama')
            ->get();

        return response()->json($prodi);
    }

    /**
     * Helper untuk mendapatkan text status akademik
     */
    private function getStatusText($status)
    {
        if (!$status)
            return '-';

        return match ($status) {
            'aktif' => 'Aktif',
            'cuti' => 'Cuti',
            'drop_out' => 'Drop Out',
            'lulus' => 'Lulus',
            'tidak_aktif' => 'Tidak Aktif',
            default => $status,
        };
    }

    /**
     * Helper untuk mendapatkan text status pengajuan
     */
    private function getPengajuanStatusText($status)
    {
        if (!$status)
            return '-';

        return match ($status) {
            'tidak_ada' => 'Tidak Ada',
            'pending' => 'Pending',
            'disetujui' => 'Disetujui',
            'ditolak' => 'Ditolak',
            default => $status,
        };
    }
}
