<?php

namespace App\Http\Controllers\Admin;

use App\Models\User;
use Inertia\Inertia;
use App\Models\Prodi;
use App\Models\Fakultas;
use Illuminate\Http\Request;
use App\Helpers\NimGenerator;
use Illuminate\Validation\Rule;
use Illuminate\Support\Facades\DB;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Redirect;

class MahasiswaProfileController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Inertia\Response
     */
    public function index(Request $request)
    {
        $filters = $request->only(['search', 'jenis_kelamin', 'prodi']);

        $query = User::with('mahasiswa.fakultas', 'mahasiswa.prodi')
            ->where('role', 'mahasiswa');

        if ($request->filled('search')) {
            $query->where(function ($q) use ($request) {
                $q->where('nim', 'like', '%' . $request->search . '%')
                    ->orWhere('name', 'like', '%' . $request->search . '%');
            });
        }

        if ($request->filled('jenis_kelamin')) {
            $query->whereHas('mahasiswa', function ($q) use ($request) {
                $q->where('jenis_kelamin', $request->jenis_kelamin);
            });
        }

        if ($request->filled('prodi')) {
            $query->whereHas('mahasiswa.prodi', function ($q) use ($request) {
                $q->where('nama', $request->prodi);
            });
        }

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

        return Inertia::render('Admin/Mahasiswa/Index', [
            'mahasiswa' => $mahasiswa,
            'prodis' => Prodi::all(['id', 'nama']),
            'filters' => $filters,
        ]);
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Inertia\Response
     */
    public function create()
    {
        $fakultas = Fakultas::with('prodis')->get();
        return Inertia::render('Admin/Mahasiswa/Create', [
            'fakultas' => $fakultas,
        ]);
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\RedirectResponse
     */
    public function store(Request $request)
    {
        $rules = [
            'nim'                  => 'required|integer|unique:'.User::class,
            'name'                  => 'required|string|max:255',
            'nik'                   => 'required|string|min:16|max:20',
            'email'                 => 'required|string|lowercase|email|max:255|unique:'.User::class,
            'profile_photo'         => 'nullable|image|mimes:jpeg,png,jpg,gif,svg|max:2048',
            'password'              => 'required|confirmed|min:6',
            'jenis_kelamin'         => ['required', Rule::in(['L', 'P'])],
            'tempat_lahir'          => 'required|string|max:100',
            'tanggal_lahir'         => 'required|date|before:today',
            'agama'                 => 'required|string|max:50',
            'alamat'                => 'required|string|max:255',
            'no_hp'                 => 'nullable|string|min:10|max:15',
            'status_perkawinan'     => 'nullable|string|max:50',
            'kewarganegaraan'       => 'nullable|string|max:50',
            'nama_ayah'             => 'nullable|string|max:100',
            'pekerjaan_ayah'        => 'nullable|string|max:100',
            'pendidikan_ayah'       => 'nullable|string|max:50',
            'penghasilan_ayah'      => 'nullable|integer',
            'nama_ibu'              => 'nullable|string|max:100',
            'pekerjaan_ibu'         => 'nullable|string|max:100',
            'pendidikan_ibu'        => 'nullable|string|max:50',
            'penghasilan_ibu'       => 'nullable|integer',
            'no_hp_orangtua'        => 'nullable|string|min:10|max:15',
            'alamat_orangtua'       => 'nullable|string|max:255',
            'nama_sekolah'          => 'nullable|string|max:150',
            'jurusan'               => 'nullable|string|max:100',
            'tahun_lulus'           => 'nullable|digits:4|integer|min:1900|max:' . now()->year,
            'fakultas_id'           => 'required|exists:fakultas,id',
            'prodi_id'              => 'required|exists:prodis,id',
            'semester'              => 'required|integer|min:1|max:8',
            'tahun_masuk'           => 'required|digits:4|integer|min:1900|max:' . now()->year,
        ];

        $messages = [
            'required'              => 'Kolom :attribute wajib diisi.',
            'string'                => 'Kolom :attribute harus berupa teks.',
            'max'                   => 'Kolom :attribute tidak boleh lebih dari :max karakter.',
            'mimes'                 => 'Kolom :attribute harus berupa file gambar.',
            'image'                 => 'Kolom :attribute harus berupa file gambar.',
            'min'                   => 'Kolom :attribute minimal harus :min karakter.',
            'confirmed'             => 'Konfirmasi :attribute tidak cocok.',
            'jenis_kelamin.in'      => 'Jenis kelamin harus L (Laki-laki) atau P (Perempuan).',
            'date'                  => 'Kolom :attribute harus berupa tanggal yang valid.',
            'before'                => 'Kolom :attribute tidak boleh di masa depan.',
            'digits'                => 'Kolom :attribute harus terdiri dari :digits digit.',
            'integer'               => 'Kolom :attribute harus berupa angka.',
            'exists'                => 'Kolom :attribute tidak valid.',
        ];

        $request->validate($rules, $messages);

        DB::transaction(function () use ($request) {
            $profilePath = null;

            if ($request->hasFile('profile_photo')) {
                $profilePath = $request->file('profile_photo')->store('profile_photos', 'public');
            }

            $user = User::create([
                'nim'      => $request->nim,
                'name'     => $request->name,
                'email'    => $request->email,
                'password' => Hash::make($request->password),
                'role'     => 'mahasiswa',
                'profile_photo' => $profilePath,
            ]);

            $user->mahasiswa()->create($request->only([
                'nik', 'jenis_kelamin', 'tempat_lahir', 'tanggal_lahir', 'agama', 'alamat', 'no_hp', 'status_perkawinan',
                'kewarganegaraan', 'nama_ayah', 'pekerjaan_ayah', 'pendidikan_ayah', 'penghasilan_ayah', 'nama_ibu',
                'pekerjaan_ibu', 'pendidikan_ibu', 'penghasilan_ibu', 'no_hp_orangtua', 'alamat_orangtua',
                'nama_sekolah', 'jurusan', 'tahun_lulus', 'fakultas_id', 'prodi_id', 'tahun_masuk', 'semester',
            ]));
        });

        return Redirect::route('mahasiswa.index')->with('success', 'Mahasiswa berhasil ditambahkan.');
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  \App\Models\User  $mahasiswa
     * @return \Inertia\Response
     */
    public function edit(User $mahasiswa)
    {
        $mahasiswa->load('mahasiswa');

        return Inertia::render('Admin/Mahasiswa/Edit', [
            'mahasiswa' => $mahasiswa,
            'fakultas'  => Fakultas::all(),
            'prodis'    => Prodi::all(),
        ]);
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \App\Models\User  $mahasiswa
     * @return \Illuminate\Http\RedirectResponse
     */
    public function update(Request $request, User $mahasiswa)
    {
        $rules = [
            'name'                  => 'required|string|max:255',
            'profile_photo'         => 'nullable|image|mimes:jpeg,jpg,png|max:2048',
            'password'              => 'nullable|confirmed|min:6',
            'jenis_kelamin'         => ['required', Rule::in(['L', 'P'])],
            'tempat_lahir'          => 'required|string|max:100',
            'tanggal_lahir'         => 'required|date|before:today',
            'agama'                 => 'required|string|max:50',
            'alamat'                => 'required|string|max:255',
            'no_hp'                 => 'nullable|string|min:10|max:15',
            'status_perkawinan'     => 'nullable|string|max:50',
            'kewarganegaraan'       => 'nullable|string|max:50',
            'nama_ayah'             => 'nullable|string|max:100',
            'pekerjaan_ayah'        => 'nullable|string|max:100',
            'pendidikan_ayah'       => 'nullable|string|max:50',
            'penghasilan_ayah'      => 'nullable|string|max:50',
            'nama_ibu'              => 'nullable|string|max:100',
            'pekerjaan_ibu'         => 'nullable|string|max:100',
            'pendidikan_ibu'        => 'nullable|string|max:50',
            'penghasilan_ibu'       => 'nullable|string|max:50',
            'no_hp_orangtua'        => 'nullable|string|min:10|max:15',
            'alamat_orangtua'       => 'nullable|string|max:255',
            'nama_sekolah'          => 'nullable|string|max:150',
            'jurusan'               => 'nullable|string|max:100',
            'tahun_lulus'           => 'nullable|digits:4|integer|min:1900|max:' . now()->year,
            'fakultas_id'           => 'required|exists:fakultas,id',
            'prodi_id'              => 'required|exists:prodis,id',
            'semester'              => 'required|integer|min:1|max:8',
            'tahun_masuk'           => 'required|digits:4|integer|min:1900|max:' . now()->year,
        ];

        $messages = [
            'required'              => 'Kolom :attribute wajib diisi.',
            'string'                => 'Kolom :attribute harus berupa teks.',
            'max'                   => 'Kolom :attribute tidak boleh lebih dari :max karakter.',
            'min'                   => 'Kolom :attribute minimal harus :min karakter.',
            'confirmed'             => 'Konfirmasi :attribute tidak cocok.',
            'jenis_kelamin.in'      => 'Jenis kelamin harus L (Laki-laki) atau P (Perempuan).',
            'date'                  => 'Kolom :attribute harus berupa tanggal yang valid.',
            'before'                => 'Kolom :attribute tidak boleh di masa depan.',
            'digits'                => 'Kolom :attribute harus terdiri dari :digits digit.',
            'integer'               => 'Kolom :attribute harus berupa angka.',
            'exists'                => 'Kolom :attribute tidak valid.',
        ];

        $request->validate($rules, $messages);

        DB::transaction(function () use ($request, $mahasiswa) {
            $profilePath = $mahasiswa->profile_photo;

            if ($request->hasFile('profile_photo')) {
                if ($mahasiswa->profile_photo && Storage::disk('public')->exists($mahasiswa->profile_photo)) {
                    Storage::disk('public')->delete($mahasiswa->profile_photo);
                }
                $profilePath = $request->file('profile_photo')->store('profile_photos', 'public');
            }
            $mahasiswa->update([
                'name'     => $request->name,
                'password' => $request->filled('password')
                    ? Hash::make($request->password)
                    : $mahasiswa->password,
                'profile_photo' => $profilePath,
            ]);

            $mahasiswa->mahasiswa()->update($request->only([
                'jenis_kelamin', 'tempat_lahir', 'tanggal_lahir', 'agama', 'alamat', 'no_hp', 'status_perkawinan',
                'kewarganegaraan', 'nama_ayah', 'pekerjaan_ayah', 'pendidikan_ayah', 'penghasilan_ayah', 'nama_ibu',
                'pekerjaan_ibu', 'pendidikan_ibu', 'penghasilan_ibu', 'no_hp_orangtua', 'alamat_orangtua',
                'nama_sekolah', 'jurusan', 'tahun_lulus', 'fakultas_id', 'prodi_id', 'semester', 'tahun_masuk',
            ]));
        });

        return Redirect::route('mahasiswa.index')->with('success', 'Data mahasiswa berhasil diperbarui.');
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  \App\Models\User  $mahasiswa
     * @return \Illuminate\Http\RedirectResponse
     */
    public function destroy(User $mahasiswa)
    {
        DB::transaction(function () use ($mahasiswa) {
            if ($mahasiswa->profile_photo && Storage::disk('public')->exists($mahasiswa->profile_photo)) {
                Storage::disk('public')->delete($mahasiswa->profile_photo);
            }
            $mahasiswa->delete();
        });

        return Redirect::route('mahasiswa.index')->with('success', 'Mahasiswa berhasil dihapus.');
    }
}
