<?php

namespace App\Http\Controllers;

use App\Models\User;
use App\Models\Student;
use App\Models\Classes;
use App\Models\Teacher;
use App\Models\Subject;
use App\Mail\SendResetPasswordLink;
use Faker\Provider\Image as ProviderImage;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Password;
use Illuminate\Validation\ValidationException;
use Intervention\Image\Facades\Image;
use Intervention\Image\Image as InterventionImage;
use Illuminate\Support\Facades\Storage;

class AuthController extends Controller
{

    public function login(Request $request)
    {
        $credentials = $request->validate([
            'email' => 'required|email',
            'password' => 'required|string',
        ]);

        if (Auth::attempt($credentials)) {
            $request->session()->regenerate();
            return redirect()->route('dashboard.index');
        }

        return back()->withErrors([
            'email' => 'Email atau password salah.',
        ])->withInput();
    }

     public function logout(Request $request)
    {
        Auth::logout();

        $request->session()->invalidate();
        $request->session()->regenerateToken();

        return redirect()->route('login');
    }

    public function showForgotPassword()
    {
        return view('auth.forgot-password');
    }

    public function sendResetLink(Request $request)
    {
        $request->validate([
            'email' => ['required', 'email'],
        ]);

        // Cek apakah email terdaftar
        $user = User::where('email', $request->email)->first();

        if (!$user) {
            return back()->withErrors(['email' => 'Email tidak ditemukan.'])->withInput($request->only('email'));
        }

        // Generate token random
        $token = \Illuminate\Support\Str::random(60);

        // Simpan token ke database dengan hashing
        DB::table('password_reset_tokens')->updateOrInsert(
            ['email' => $request->email],
            [
                'token' => Hash::make($token),
                'created_at' => now(),
            ]
        );

        // Kirim email dengan link reset password dan token
        try {
            Mail::to($request->email)->send(new SendResetPasswordLink($request->email, $token));
        } catch (\Exception $e) {
            return back()->withErrors(['email' => 'Gagal mengirim email. Silakan coba lagi.'])->withInput($request->only('email'));
        }

        return redirect()->route('password.verify.form', [
            'email' => $request->email,
        ])->with('status', 'Email reset password telah dikirim. Silakan cek email Anda untuk token. Token berlaku selama 60 menit.');
    }

    public function showVerifyToken(Request $request)
    {
        if (!$request->filled('email')) {
            return redirect()->route('password.request');
        }

        // Cek apakah ada token untuk email ini yang masih berlaku
        $resetToken = DB::table('password_reset_tokens')
            ->where('email', $request->email)
            ->where('created_at', '>=', now()->subMinutes(60))
            ->first();

        if (!$resetToken) {
            return redirect()->route('password.request')
                ->withErrors(['email' => 'Token tidak ditemukan atau sudah kadaluarsa.']);
        }

        $email = $request->email;
        return view('auth.verify-token', compact('email'));
    }

    public function verifyToken(Request $request)
    {
        $request->validate([
            'email' => ['required', 'email'],
            'token' => ['required', 'string'],
        ]);

        // Cek token di database
        $resetToken = DB::table('password_reset_tokens')
            ->where('email', $request->email)
            ->where('created_at', '>=', now()->subMinutes(60))
            ->first();

        if (!$resetToken) {
            return back()->withErrors(['email' => 'Token tidak ditemukan atau sudah kadaluarsa.']);
        }

        // Verifikasi token
        if (!Hash::check($request->token, $resetToken->token)) {
            return back()->withErrors(['token' => 'Token tidak sesuai.'])->withInput();
        }

        // Token valid, arahkan ke form confirm password
        return redirect()->route('password.confirm.form', [
            'email' => $request->email,
        ])->with('status', 'Token terverifikasi. Silakan masukkan password baru.');
    }

    public function showConfirmPassword(Request $request)
    {
        if (!$request->filled('email')) {
            return redirect()->route('password.request')
                ->withErrors(['email' => 'Link konfirmasi password tidak valid.']);
        }

        $email = $request->email;
        return view('auth.confirm-password', compact('email'));
    }

    public function updatePassword(Request $request)
    {
        $request->validate([
            'email' => ['required', 'email'],
            'password' => ['required', 'confirmed', 'min:8'],
        ], [
            'password.confirmed' => 'Konfirmasi password tidak sesuai.',
            'password.min' => 'Password minimal 8 karakter.',
        ]);

        // Cek user
        $user = User::where('email', $request->email)->first();

        if (!$user) {
            return back()->withErrors(['email' => 'Email tidak ditemukan.']);
        }

        // Jika user adalah admin (forgot password langsung ke confirm password)
        $isAdmin = $user->role === 'admin';

        // Jika user bukan admin, cek token (dari verify token flow)
        if (!$isAdmin) {
            $resetToken = DB::table('password_reset_tokens')
                ->where('email', $request->email)
                ->where('created_at', '>=', now()->subMinutes(60))
                ->first();

            if (!$resetToken) {
                return back()->withErrors(['email' => 'Session reset password telah kadaluarsa. Silakan lakukan forgot password lagi.']);
            }
        }

        // Update password
        $user->password = Hash::make($request->password);
        $user->save();

        // Hapus token dari database jika ada
        DB::table('password_reset_tokens')
            ->where('email', $request->email)
            ->delete();

        $message = $isAdmin ? 'Password admin berhasil diperbarui. Silakan login.' : 'Password berhasil direset. Silakan login dengan password baru Anda.';
        return redirect()->route('login')->with('success', $message);
    }

    public function showSetting()
    {
        $user = Auth::user();

        return view('pages.setting.setting', compact('user'));
    }

    public function updateSetting(Request $request)
    {
        $user = Auth::user();

        if (!$user) {
            return redirect()->route('login');
        }

        if ($request->input('form_type') === 'profile') {
            return $this->updateSettingProfile($request, $user);
        }

        if ($request->input('form_type') === 'password') {
            return $this->updateSettingPassword($request, $user);
        }

        return back()->withErrors(['form' => 'Form tidak valid.']);
    }

    public function deleteProfilePicture()
    {
        $user = Auth::user();

        if (!$user instanceof User) {
            return redirect()->route('login');
        }

        if (empty($user->profile_picture)) {
            return back()->with('success', 'Foto profil sudah kosong.');
        }

        $rolePath = $user->role ?? 'others';
        if (!empty($user->profile_picture) && Storage::disk('public')->exists('profile_pictures/' . $rolePath . '/' . $user->profile_picture)) {
            Storage::disk('public')->delete('profile_pictures/' . $rolePath . '/' . $user->profile_picture);
        }

        $user->profile_picture = null;
        $user->save();

        return back()->with('success', 'Foto profil berhasil dihapus.');
    }

    private function updateSettingProfile(Request $request, User $user)
    {
        $request->validate([
            'email' => 'required|email|max:255|unique:users,email,' . $user->id,
            'profile_picture' => 'nullable|image|mimes:jpeg,png,jpg,gif,webp|max:2048',
        ]);

        $user->email = $request->email;

        if ($request->hasFile('profile_picture')) {
            $rolePath = $user->role ?? 'others';
            if (!empty($user->profile_picture) && Storage::disk('public')->exists('profile_pictures/' . $rolePath . '/' . $user->profile_picture)) {
                Storage::disk('public')->delete('profile_pictures/' . $rolePath . '/' . $user->profile_picture);
            }

            $image = $request->file('profile_picture');
            $imageName = $image->hashName();
            Storage::disk('public')->putFileAs('profile_pictures/' . $rolePath, $image, $imageName);
            $user->profile_picture = $imageName;
        }

        $user->save();

        return back()->with('success', 'Email dan gambar profil berhasil diperbarui.');
    }

    private function updateSettingPassword(Request $request, User $user)
    {
        $request->validate([
            'current_password' => 'required|string',
            'new_password' => 'required|string|min:8|confirmed',
        ], [
            'new_password.confirmed' => 'Konfirmasi password baru tidak cocok.',
        ]);

        if (!Hash::check($request->current_password, $user->password)) {
            return back()->withErrors([
                'current_password' => 'Password saat ini tidak sesuai.',
            ]);
        }

        $user->password = Hash::make($request->new_password);
        $user->save();

        return back()->with('success', 'Password berhasil diperbarui.');
    }

    // start register student
    public function registerStudent(Request $request)
    {
        try {
            $request->validate([
                'name' => 'required|string|max:255',
                'email' => 'required|string|email|max:255|unique:users',
                'password' => 'required|string|min:6',
                'nisn' => 'required|digits:10|unique:students,nisn',
                'id_class' => 'required|integer',
                'entry_year' => 'required|integer',
                'profile_picture' => 'nullable|image|mimes:jpeg,png,jpg,gif,svg|max:2048',
                'pictures' => 'nullable|string',
            ]);

            // Proses upload gambar jika ada
            $imageName = null;
            if ($request->hasFile('profile_picture')) {
                $image = $request->file('profile_picture');
                $imageName = $image->hashName();
                Storage::disk('public')->putFileAs('profile_pictures/student', $image, $imageName);
            }

            // Proses 3 foto webcam
            $picturesNames = [];
            if ($request->filled('pictures')) {
                $photosData = $request->pictures;
                $photoArray = explode('|||', $photosData); // Split dengan |||


                foreach ($photoArray as $index => $photo) {
                    if (!empty($photo)) {
                        $imageData = $photo;

                        if (strpos($imageData, ',') !== false) {
                            list($type, $imageData) = explode(',', $imageData);
                            $imageData = base64_decode($imageData);
                        } else {
                            $imageData = base64_decode($imageData);
                        }

                        if ($imageData !== false) {
                            $picturesName = 'webcam_' . time() . '_' . ($index + 1) . '_' . uniqid() . '.png';
                            Storage::disk('public')->put('photo-webcam/' . $picturesName, $imageData);
                            $picturesNames[] = $picturesName;
                        }
                    }
                }
            }

            $user = User::create([
                'email' => $request->email,
                'password' => Hash::make($request->password),
                'role' => 'student',
                'profile_picture' => $imageName,
            ]);

            $user->student()->create([
                'id_user' => $user->id,
                'name' => $request->name,
                'nisn' => $request->nisn,
                'id_class' => $request->id_class,
                'entry_year' => $request->entry_year,
                'pictures' => !empty($picturesNames) ? implode(',', $picturesNames) : null,
            ]);

            // Redirect kembali ke identitas siswa dengan pesan sukses
            return redirect()->route('akun.indentitas_siswa')->with('success', 'Data siswa berhasil ditambahkan.');
        } catch (ValidationException $e) {
            return redirect()->back()
                ->withErrors($e->errors())
                ->withInput()
                ->with('open_modal', 'tambah');
        } catch (\Exception $e) {
            return redirect()->back()
                ->with('error', 'Registrasi siswa gagal. Silakan coba lagi.')
                ->withInput()
                ->with('open_modal', 'tambah');
        }
    }



    public function identitasSiswa()
    {
        $students = Student::with(['user', 'class'])->get();
        $classes = Classes::all();
        return view('pages.akun.indentitas_siswa', compact('students', 'classes'));
    }

    public function destroyStudent($id)
    {
        $student = Student::findOrFail($id);

        // Hapus semua foto webcam jika ada
        if ($student->pictures) {
            $photos = explode(',', $student->pictures);
            foreach ($photos as $photo) {
                if (!empty($photo)) {
                    if (Storage::disk('public')->exists('photo-webcam/' . $photo)) {
                        Storage::disk('public')->delete('photo-webcam/' . $photo);
                    }
                }
            }
        }

        // Hapus user terkait (akan otomatis hapus student jika foreign key cascade)
        if ($student->user) {
            $student->user->delete();
        } else {
            $student->delete();
        }
        return redirect()->route('akun.indentitas_siswa')->with('success', 'Data siswa berhasil dihapus.');
    }

    public function updateStudent(Request $request, $id)
    {
        try {
            // Jika massal (hanya update kelas)
            if ($request->has('id_class') && !$request->has('name')) {
                $student = Student::findOrFail($id);
                $student->id_class = $request->id_class;
                $student->save();
                return redirect()->route('akun.indentitas_siswa')->with('success', 'Kelas siswa berhasil diupdate.');
            }

            // Update lengkap (dari modal edit)
            $student = Student::findOrFail($id);
            $user = $student->user;

            $request->validate([
                'name' => 'required|string|max:255',
                'email' => 'required|string|email|max:255|unique:users,email,' . $user->id,
                'nisn' => 'required|digits:10|unique:students,nisn,' . $student->id,
                'id_class' => 'required|integer',
                'entry_year' => 'required|integer',
                'profile_picture' => 'nullable|image|mimes:jpeg,png,jpg,gif,svg|max:2048',
                'pictures_edit' => 'nullable|string',
                'delete_webcam_photo' => 'nullable|string',
            ]);

            $user->email = $request->email;
            if ($request->hasFile('profile_picture')) {
                // Hapus foto lama jika ada
                if ($user->profile_picture && Storage::disk('public')->exists('profile_pictures/student/' . $user->profile_picture)) {
                    Storage::disk('public')->delete('profile_pictures/student/' . $user->profile_picture);
                }

                $image = $request->file('profile_picture');
                $imageName = $image->hashName();
                Storage::disk('public')->putFileAs('profile_pictures/student', $image, $imageName);
                $user->profile_picture = $imageName;
            }
            $user->save();

            $student->name = $request->name;
            $student->nisn = $request->nisn;
            $student->id_class = $request->id_class;
            $student->entry_year = $request->entry_year;

            // Handle hapus foto webcam lama
            if ($request->filled('delete_webcam_photo') && $request->delete_webcam_photo == '1') {
                if ($student->pictures) {
                    $photos = explode(',', $student->pictures);
                    foreach ($photos as $photo) {
                        if (!empty($photo) && Storage::disk('public')->exists('photo-webcam/' . $photo)) {
                            Storage::disk('public')->delete('photo-webcam/' . $photo);
                        }
                    }
                }
                $student->pictures = null;
            }

            // Handle tambah foto webcam baru dari edit (3 foto)
            if ($request->filled('pictures_edit')) {
                $photosData = $request->pictures_edit;
                $photoArray = explode('|||', $photosData); // Split dengan |||

                // Hapus foto lama dulu sebelum menyimpan yang baru
                if ($student->pictures) {
                    $oldPhotos = explode(',', $student->pictures);
                    foreach ($oldPhotos as $photo) {
                        if (!empty($photo) && Storage::disk('public')->exists('photo-webcam/' . $photo)) {
                            Storage::disk('public')->delete('photo-webcam/' . $photo);
                        }
                    }
                }

                $picturesNames = [];
                foreach ($photoArray as $index => $photo) {
                    if (!empty($photo)) {
                        $imageData = $photo;

                        if (strpos($imageData, ',') !== false) {
                            list($type, $imageData) = explode(',', $imageData);
                            $imageData = base64_decode($imageData);
                        } else {
                            $imageData = base64_decode($imageData);
                        }

                        if ($imageData !== false) {
                            $picturesName = 'webcam_' . time() . '_' . ($index + 1) . '_' . uniqid() . '.png';
                            Storage::disk('public')->put('photo-webcam/' . $picturesName, $imageData);
                            $picturesNames[] = $picturesName;
                        }
                    }
                }

                if (!empty($picturesNames)) {
                    $student->pictures = implode(',', $picturesNames);
                }
            }

            $student->save();

            return redirect()->route('akun.indentitas_siswa')->with('success', 'Data siswa berhasil diupdate.');
        } catch (ValidationException $e) {
            return redirect()->back()
                ->withErrors($e->errors())
                ->withInput()
                ->with('open_modal', 'edit')
                ->with('edit_id', $id);
        } catch (\Exception $e) {
            return redirect()->back()
                ->with('error', 'Update siswa gagal. Silakan coba lagi.')
                ->withInput()
                ->with('open_modal', 'edit')
                ->with('edit_id', $id);
        }
    }

    public function updateStudentClass(Request $request, $id)
    {
        $request->validate([
            'id_class' => 'required|integer',
        ]);

        $student = Student::findOrFail($id);
        $student->id_class = $request->id_class;
        $student->save();

        return redirect()->route('akun.indentitas_siswa')->with('success', 'Kelas siswa berhasil diupdate.');
    }

    // end register student


    // start register teacher
     public function registerTeacher(Request $request)
    {
        try {
            $request->validate([
                'name' => 'required|string|max:255',
                'email' => 'required|string|email|max:255|unique:users',
                'password' => 'required|string|min:6',
                'nip' => 'required|digits:18|unique:teachers,nip',
                'subjects' => 'required|array|min:1',
                'subjects.*' => 'integer|exists:subjects,id',
                'profile_picture' => 'nullable|image|mimes:jpeg,png,jpg,gif,svg|max:2048',
            ]);

            $imageName = null;
            if ($request->hasFile('profile_picture')) {
                $image = $request->file('profile_picture');
                $imageName = $image->hashName();
                Storage::disk('public')->putFileAs('profile_pictures/teacher', $image, $imageName);
            }

            // Ambil nama semua subject yang dipilih
            $subjectNames = Subject::whereIn('id', $request->subjects)->pluck('code')->toArray();
            $subjectString = implode(', ', $subjectNames);

            $user = User::create([
                'email' => $request->email,
                'password' => Hash::make($request->password),
                'role' => 'teacher',
                'profile_picture' => $imageName,
            ]);

            $teacher = new Teacher();
            $teacher->id_user = $user->id;
            $teacher->name = $request->name;
            $teacher->nip = $request->nip;
            $teacher->subject = $subjectString;
            $teacher->save();

            return redirect()->route('akun.indentitas_guru')->with('success', 'Data guru berhasil ditambahkan.');
        } catch (ValidationException $e) {
            return redirect()->back()
                ->withErrors($e->errors())
                ->withInput()
                ->with('open_modal', 'tambah');
        } catch (\Exception $e) {
            return redirect()->back()
                ->with('error', 'Registrasi guru gagal: ' . $e->getMessage())
                ->withInput()
                ->with('open_modal', 'tambah');
        }
    }

    public function identitasGuru()
    {
        $teachers = Teacher::with('user')->get(); // Hapus 'subjects'
        $subjects = Subject::all();



        return view('pages.akun.indentitas_guru', compact('teachers', 'subjects'));
    }

    // Update teacher


    public function updateTeacher(Request $request, $id)
    {
        try {
            $teacher = Teacher::findOrFail($id);
            $user = $teacher->user;

            $request->validate([
                'name' => 'required|string|max:255',
                'email' => 'required|string|email|max:255|unique:users,email,' . $user->id,
                'nip' => 'required|string|max:50|unique:teachers,nip,' . $teacher->id,
                'subjects' => 'required|array|min:1',
                'subjects.*' => 'integer|exists:subjects,id',
                'profile_picture' => 'nullable|image|mimes:jpeg,png,jpg,gif,svg|max:2048',
            ]);

            $user->email = $request->email;
            if ($request->hasFile('profile_picture')) {
                if ($user->profile_picture && Storage::disk('public')->exists('profile_pictures/teacher/' . $user->profile_picture)) {
                    Storage::disk('public')->delete('profile_pictures/teacher/' . $user->profile_picture);
                }

                $image = $request->file('profile_picture');
                $imageName = $image->hashName();
                Storage::disk('public')->putFileAs('profile_pictures/teacher', $image, $imageName);
                $user->profile_picture = $imageName;
            }
            $user->save();

            // Ambil nama semua subject yang dipilih
            $subjectNames = Subject::whereIn('id', $request->subjects)->pluck('code')->toArray();
            $subjectString = implode(', ', $subjectNames);

            $teacher->name = $request->name;
            $teacher->nip = $request->nip;
            $teacher->subject = $subjectString;
            $teacher->save();

            return redirect()->route('akun.indentitas_guru')->with('success', 'Data guru berhasil diupdate.');
        } catch (\Illuminate\Validation\ValidationException $e) {
            return redirect()->back()
                ->withErrors($e->errors())
                ->withInput()
                ->with('open_modal', 'edit')
                ->with('edit_id', $id);
        } catch (\Exception $e) {
            return redirect()->back()
                ->with('error', 'Update guru gagal. Silakan coba lagi.')
                ->withInput()
                ->with('open_modal', 'edit')
                ->with('edit_id', $id);
        }
    }

    public function destroyTeacher($id)
    {
        $teacher = Teacher::findOrFail($id);
        // Hapus user terkait (akan otomatis hapus teacher jika foreign key cascade)
        if ($teacher->user) {
            $teacher->user->delete();
        } else {
            $teacher->delete();
        }
        return redirect()->route('akun.indentitas_guru')->with('success', 'Data guru berhasil dihapus.');
    }
}



