<?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 ValidasiPengajuanController extends Controller
{
    /**
     * Daftar pengajuan pending
     */
    public function index(Request $request)
    {
        $user = Auth::user();
        $isGlobal = $user->role->name === 'superadmin' || $user->role->name === 'admin';

        $query = Mahasiswa::with(['kampus', 'prodi', 'pengaju'])
            ->where('pengajuan_status', 'pending')
            ->orderBy('pengajuan_at', 'asc');

        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->jenis && $request->jenis !== '' && $request->jenis !== 'all') {
            $query->where('pengajuan_jenis', $request->jenis);
        }

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

        $pengajuan = $query->paginate(10)->withQueryString();
        $kampusList = $isGlobal ? Kampus::select('id', 'nama', 'singkatan')->get() : collect([]);

        $statistics = [
            'total' => Mahasiswa::where('pengajuan_status', 'pending')->count(),
            'aktif' => Mahasiswa::where('pengajuan_status', 'pending')->where('pengajuan_jenis', 'aktif')->count(),
            'cuti' => Mahasiswa::where('pengajuan_status', 'pending')->where('pengajuan_jenis', 'cuti')->count(),
            'drop_out' => Mahasiswa::where('pengajuan_status', 'pending')->where('pengajuan_jenis', 'drop_out')->count(),
            'lulus' => Mahasiswa::where('pengajuan_status', 'pending')->where('pengajuan_jenis', 'lulus')->count(),
            'tidak_aktif' => Mahasiswa::where('pengajuan_status', 'pending')->where('pengajuan_jenis', 'tidak_aktif')->count(),
        ];

        return view('validasi.pengajuan-status', compact('pengajuan', 'statistics', 'kampusList'));
    }

    /**
     * Detail pengajuan (AJAX)
     */
    public function show($id)
    {
        try {
            $mahasiswa = Mahasiswa::with(['kampus', 'prodi', 'pengaju', 'validatorPengajuan'])
                ->findOrFail($id);

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

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

            return response()->json([
                '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_at' => $mahasiswa->pengajuan_at ? $mahasiswa->pengajuan_at->format('d/m/Y H:i') : null,
                'pengajuan_by' => $mahasiswa->pengaju->name ?? '-',
                'cuti_semester' => $cutiText,
                'cuti_history_text' => $cutiText ? 'Semester ' . $cutiText : '-',
                '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,
            ]);

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

    /**
     * Setujui pengajuan (AJAX)
     */
    public function approve($id)
    {
        $mahasiswa = Mahasiswa::findOrFail($id);

        if ($mahasiswa->pengajuan_status !== 'pending') {
            return response()->json([
                'success' => false,
                'message' => 'Pengajuan sudah diproses.'
            ], 400);
        }

        DB::beginTransaction();
        try {
            $pengajuanJenis = $mahasiswa->pengajuan_jenis;

            // Jika pengajuan adalah cuti, ambil semester cuti dari session
            if ($pengajuanJenis === 'cuti') {
                $cutiSemester = session('pending_cuti_semester_' . $mahasiswa->id);

                if ($cutiSemester) {
                    // Ambil cuti_semester yang sudah ada (history)
                    $existingCuti = $mahasiswa->cuti_semester;

                    if (is_string($existingCuti) && str_starts_with($existingCuti, '[')) {
                        $existingCuti = json_decode($existingCuti, true);
                    }
                    if (!is_array($existingCuti)) {
                        $existingCuti = [];
                    }

                    // Tambahkan cuti baru ke history
                    if (!in_array($cutiSemester, $existingCuti)) {
                        $existingCuti[] = $cutiSemester;
                        sort($existingCuti);
                    }
                    $mahasiswa->cuti_semester = json_encode($existingCuti);

                    // Hapus session
                    session()->forget('pending_cuti_semester_' . $mahasiswa->id);
                }
            }

            // Update status akademik sesuai pengajuan
            $mahasiswa->status_akademik = $pengajuanJenis;

            // Reset pengajuan
            $mahasiswa->pengajuan_status = 'tidak_ada';
            $mahasiswa->pengajuan_jenis = null;
            $mahasiswa->pengajuan_validasi_at = now();
            $mahasiswa->pengajuan_validasi_by = Auth::id();

            $mahasiswa->save();

            // Jika pengajuan adalah cuti, perpanjang angsuran
            if ($pengajuanJenis === 'cuti') {
                $angsuranController = app(\App\Http\Controllers\AngsuranController::class);
                $angsuranController->extendAngsuranJikaCuti($mahasiswa);
            }

            DB::commit();

            return response()->json([
                'success' => true,
                'message' => "Status mahasiswa {$mahasiswa->nama} berhasil diubah menjadi " .
                    $this->getStatusText($mahasiswa->status_akademik) . "."
            ]);

        } catch (\Exception $e) {
            DB::rollBack();
            Log::error('Gagal menyetujui pengajuan: ' . $e->getMessage());
            return response()->json([
                'success' => false,
                'message' => 'Terjadi kesalahan: ' . $e->getMessage()
            ], 500);
        }
    }

    /**
     * Tolak pengajuan (AJAX)
     */
    public function reject($id)
    {
        $mahasiswa = Mahasiswa::findOrFail($id);

        if ($mahasiswa->pengajuan_status !== 'pending') {
            return response()->json([
                'success' => false,
                'message' => 'Pengajuan sudah diproses.'
            ], 400);
        }

        DB::beginTransaction();
        try {
            // Hapus file-file terkait
            if ($mahasiswa->pengajuan_file) {
                Storage::disk('public')->delete($mahasiswa->pengajuan_file);
            }
            if ($mahasiswa->bukti_bayar_file) {
                Storage::disk('public')->delete($mahasiswa->bukti_bayar_file);
            }

            // Reset data pengajuan
            $mahasiswa->pengajuan_status = 'tidak_ada';
            $mahasiswa->pengajuan_jenis = null;
            $mahasiswa->pengajuan_file = null;
            $mahasiswa->bukti_bayar_file = null;
            $mahasiswa->pengajuan_at = null;
            $mahasiswa->pengajuan_by = null;
            $mahasiswa->pengajuan_validasi_at = now();
            $mahasiswa->pengajuan_validasi_by = Auth::id();

            $mahasiswa->save();

            DB::commit();

            return response()->json([
                'success' => true,
                'message' => "Pengajuan status mahasiswa {$mahasiswa->nama} ditolak."
            ]);

        } catch (\Exception $e) {
            DB::rollBack();
            Log::error('Gagal menolak pengajuan: ' . $e->getMessage());
            return response()->json([
                'success' => false,
                'message' => 'Terjadi kesalahan: ' . $e->getMessage()
            ], 500);
        }
    }

    /**
     * Bulk approve/reject
     */
    public function bulkAction(Request $request)
    {
        $request->validate([
            'ids' => 'required|array',
            'ids.*' => 'exists:mahasiswa,id',
            'action' => 'required|in:approve,reject',
        ]);

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

            foreach ($request->ids as $id) {
                try {
                    $m = Mahasiswa::find($id);

                    if (!$m) {
                        $errors[] = "Mahasiswa dengan ID {$id} tidak ditemukan";
                        continue;
                    }

                    if ($request->action === 'approve') {
                        $pengajuanJenis = $m->pengajuan_jenis;

                        // Jika pengajuan adalah cuti, ambil semester cuti dari session
                        if ($pengajuanJenis === 'cuti') {
                            $cutiSemester = session('pending_cuti_semester_' . $m->id);

                            if ($cutiSemester) {
                                $existingCuti = $m->cuti_semester;

                                if (is_string($existingCuti) && str_starts_with($existingCuti, '[')) {
                                    $existingCuti = json_decode($existingCuti, true);
                                }
                                if (!is_array($existingCuti)) {
                                    $existingCuti = [];
                                }

                                if (!in_array($cutiSemester, $existingCuti)) {
                                    $existingCuti[] = $cutiSemester;
                                    sort($existingCuti);
                                }
                                $m->cuti_semester = json_encode($existingCuti);

                                session()->forget('pending_cuti_semester_' . $m->id);
                            }
                        }

                        // Update status akademik
                        $m->status_akademik = $pengajuanJenis;

                        // Reset pengajuan
                        $m->pengajuan_status = 'tidak_ada';
                        $m->pengajuan_jenis = null;
                        $m->pengajuan_validasi_at = now();
                        $m->pengajuan_validasi_by = Auth::id();

                        $m->save();

                        // Jika pengajuan adalah cuti, perpanjang angsuran
                        if ($pengajuanJenis === 'cuti') {
                            $angsuranController = app(\App\Http\Controllers\AngsuranController::class);
                            $angsuranController->extendAngsuranJikaCuti($m);
                        }

                    } else {
                        // Reject
                        if ($m->pengajuan_file) {
                            Storage::disk('public')->delete($m->pengajuan_file);
                        }
                        if ($m->bukti_bayar_file) {
                            Storage::disk('public')->delete($m->bukti_bayar_file);
                        }

                        $m->pengajuan_status = 'tidak_ada';
                        $m->pengajuan_jenis = null;
                        $m->pengajuan_file = null;
                        $m->bukti_bayar_file = null;
                        $m->pengajuan_at = null;
                        $m->pengajuan_by = null;
                        $m->pengajuan_validasi_at = now();
                        $m->pengajuan_validasi_by = Auth::id();

                        $m->save();
                    }

                    $processedCount++;
                } catch (\Exception $e) {
                    $errors[] = "ID {$id}: " . $e->getMessage();
                }
            }

            DB::commit();

            $actionText = $request->action === 'approve' ? 'disetujui' : 'ditolak';
            $message = "{$processedCount} pengajuan berhasil {$actionText}.";

            if (!empty($errors)) {
                $message .= " Beberapa gagal diproses: " . implode(', ', $errors);
            }

            return response()->json([
                'success' => true,
                'message' => $message
            ]);

        } catch (\Exception $e) {
            DB::rollBack();
            Log::error('Gagal bulk action: ' . $e->getMessage());
            return response()->json([
                'success' => false,
                'message' => 'Terjadi kesalahan: ' . $e->getMessage()
            ], 500);
        }
    }

    /**
     * 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);
    }

    /**
     * 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,
        };
    }
}
