<?php

namespace App\Http\Controllers;

use App\Models\Applicant;
use App\Models\MessageTemplate;
use App\Models\Setting;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Str;

class PasswordController extends Controller
{
    /**
     * Show change password form (requires login)
     */
    public function showChangeForm()
    {
        $applicantId = session('applicant_id');
        if (!$applicantId) return redirect()->route('login');

        $applicant = Applicant::findOrFail($applicantId);
        return view('auth.change-password', compact('applicant'));
    }

    /**
     * Process change password
     */
    public function changePassword(Request $request)
    {
        $applicantId = session('applicant_id');
        if (!$applicantId) return redirect()->route('login');

        $applicant = Applicant::findOrFail($applicantId);

        $request->validate([
            'current_password' => 'required',
            'password' => 'required|string|min:6|confirmed',
        ], [
            'current_password.required' => 'Password saat ini wajib diisi.',
            'password.required' => 'Password baru wajib diisi.',
            'password.min' => 'Password baru minimal 6 karakter.',
            'password.confirmed' => 'Konfirmasi password tidak cocok.',
        ]);

        // Verify current password
        if (!Hash::check($request->current_password, $applicant->password)) {
            return back()->withErrors(['current_password' => 'Password saat ini salah.']);
        }

        $applicant->update([
            'password' => $request->password,
        ]);

        // Regenerate session for security (re-login with new session)
        $request->session()->regenerate();

        return redirect()->route('dashboard')->with('success', 'Password berhasil diubah!');
    }

    /**
     * Show forgot password form
     */
    public function showForgotForm()
    {
        return view('auth.forgot-password');
    }

    /**
     * Send password reset link via email & WhatsApp
     */
    public function sendResetLink(Request $request)
    {
        $request->validate([
            'email' => 'required|email',
        ], [
            'email.required' => 'Email wajib diisi.',
            'email.email' => 'Format email tidak valid.',
        ]);

        // Rate limiting: max 3 reset requests per email per 15 minutes
        $cacheKey = 'password_reset_' . md5($request->email);
        $attempts = (int) cache($cacheKey, 0);
        if ($attempts >= 3) {
            return back()->withErrors(['email' => 'Terlalu banyak permintaan reset. Silakan coba lagi dalam 15 menit.']);
        }
        cache([$cacheKey => $attempts + 1], now()->addMinutes(15));

        $applicant = Applicant::where('email', $request->email)->first();

        if (!$applicant) {
            // Return generic success message to prevent user enumeration
            return back()->with('success', 'Jika email terdaftar di sistem kami, link reset password akan dikirim. Silakan cek inbox atau folder spam.');
        }

        // Delete old tokens for this email
        DB::table('applicant_password_resets')->where('email', $request->email)->delete();

        // Generate token
        $token = Str::random(64);
        DB::table('applicant_password_resets')->insert([
            'email' => $request->email,
            'token' => Hash::make($token),
            'created_at' => now(),
        ]);

        $resetUrl = route('password.reset', ['token' => $token, 'email' => $request->email]);

        // Build message from template
        $msg = $this->buildResetMessage($applicant, $resetUrl);

        // Send email
        try {
            Mail::html($this->buildResetEmailHtml($applicant->name, $msg['email_body']), function ($mail) use ($applicant, $msg) {
                $mail->to($applicant->email, $applicant->name)
                    ->subject($msg['subject']);
            });
        } catch (\Exception $e) {
            Log::error('Reset password email failed: ' . $e->getMessage());
        }

        // Send WhatsApp via Fonnte if available
        $this->sendResetWhatsApp($applicant, $msg['wa_body']);

        return back()->with('success', 'Link reset password telah dikirim ke email Anda. Silakan cek inbox atau folder spam.');
    }

    /**
     * Show reset password form
     */
    public function showResetForm(Request $request)
    {
        $token = $request->query('token');
        $email = $request->query('email');

        if (!$token || !$email) {
            return redirect()->route('login')->with('error', 'Link reset password tidak valid.');
        }

        return view('auth.reset-password', compact('token', 'email'));
    }

    /**
     * Process password reset
     */
    public function resetPassword(Request $request)
    {
        $request->validate([
            'email' => 'required|email',
            'token' => 'required',
            'password' => 'required|string|min:6|confirmed',
        ], [
            'password.required' => 'Password baru wajib diisi.',
            'password.min' => 'Password baru minimal 6 karakter.',
            'password.confirmed' => 'Konfirmasi password tidak cocok.',
        ]);

        // Verify token
        $resetRecord = DB::table('applicant_password_resets')
            ->where('email', $request->email)
            ->first();

        if (!$resetRecord) {
            return back()->withErrors(['email' => 'Token reset password tidak ditemukan.']);
        }

        // Check if token has expired (60 minutes)
        if (now()->diffInMinutes($resetRecord->created_at) > 60) {
            DB::table('applicant_password_resets')->where('email', $request->email)->delete();
            return back()->withErrors(['email' => 'Token reset password sudah kedaluwarsa. Silakan request ulang.']);
        }

        // Verify the token
        if (!Hash::check($request->token, $resetRecord->token)) {
            return back()->withErrors(['email' => 'Token reset password tidak valid.']);
        }

        // Update password
        $applicant = Applicant::where('email', $request->email)->first();
        if (!$applicant) {
            return back()->withErrors(['email' => 'Akun tidak ditemukan.']);
        }

        $applicant->update([
            'password' => $request->password,
        ]);

        // Delete used token
        DB::table('applicant_password_resets')->where('email', $request->email)->delete();

        return redirect()->route('login')->with('success', 'Password berhasil direset! Silakan login dengan password baru Anda.');
    }

    /**
     * Build the reset password message using the template system
     */
    private function buildResetMessage(Applicant $applicant, string $resetUrl): array
    {
        $siteName = Setting::get('site_name', config('app.name', 'Bursa Kerja'));
        $siteUrl = config('app.url');

        $variables = [
            'applicant_name' => $applicant->name ?? 'Pelamar',
            'email' => $applicant->email ?? '',
            'reset_url' => $resetUrl,
            'site_name' => $siteName,
            'site_url' => $siteUrl,
        ];

        // Try to load template from DB
        $template = MessageTemplate::getByType('password_reset');

        if ($template) {
            $result = [
                'subject' => MessageTemplate::render($template->email_subject ?? '', $variables),
                'email_body' => MessageTemplate::render($template->email_body ?? '', $variables),
                'wa_body' => MessageTemplate::render($template->wa_body ?? '', $variables),
            ];

            return $result;
        }

        // Hardcoded fallback
        return [
            'subject' => "Reset Password - {$siteName}",
            'email_body' => "Kami menerima permintaan untuk mereset password akun Anda di <strong>{$siteName}</strong>.<br><br>Klik link berikut untuk membuat password baru:<br><a href=\"{$resetUrl}\">{$resetUrl}</a><br><br><em>Link ini hanya berlaku selama 60 menit.</em><br><br>Jika Anda tidak merasa meminta reset password, abaikan email ini.",
            'wa_body' => "Halo *{$applicant->name}*,\n\nKami menerima permintaan reset password untuk akun Anda di *{$siteName}*.\n\nKlik link berikut untuk membuat password baru:\n{$resetUrl}\n\n⏰ Link berlaku 60 menit.\n\nJika Anda tidak merasa meminta reset password, abaikan pesan ini.",
        ];
    }

    /**
     * Build HTML for reset password email
     */
    private function buildResetEmailHtml(string $name, string $emailBody): string
    {
        $appName = Setting::get('site_name', config('app.name', 'Bursa Kerja'));

        return <<<HTML
        <!DOCTYPE html>
        <html>
        <head>
            <meta charset="UTF-8">
            <style>
                body { font-family: 'Segoe UI', Arial, sans-serif; background: #f5f7fa; margin: 0; padding: 0; }
                .container { max-width: 600px; margin: 30px auto; background: #ffffff; border-radius: 12px; overflow: hidden; box-shadow: 0 2px 12px rgba(0,0,0,0.08); }
                .header { background: linear-gradient(135deg, #4f46e5, #7c3aed); padding: 30px; text-align: center; }
                .header h1 { color: #ffffff; font-size: 22px; margin: 0; }
                .body { padding: 30px; }
                .body p { color: #374151; font-size: 15px; line-height: 1.6; }
                .btn { display: inline-block; background: #4f46e5; color: #ffffff !important; padding: 14px 32px; border-radius: 8px; text-decoration: none; font-weight: 600; font-size: 15px; margin: 20px 0; }
                .footer { padding: 20px 30px; background: #f9fafb; text-align: center; }
                .footer p { color: #9ca3af; font-size: 12px; margin: 0; }
                .warning { background: #fef3c7; border: 1px solid #fcd34d; border-radius: 8px; padding: 12px 16px; margin: 16px 0; }
                .warning p { color: #92400e; font-size: 13px; margin: 0; }
            </style>
        </head>
        <body>
            <div class="container">
                <div class="header">
                    <h1>🔒 Reset Password</h1>
                </div>
                <div class="body">
                    <p>Halo <strong>{$name}</strong>,</p>
                    <div style="background: #F9FAFB; border-radius: 8px; padding: 15px; margin: 15px 0;">
                        {$emailBody}
                    </div>
                </div>
                <div class="footer">
                    <p>&copy; 2026 {$appName}. Semua hak dilindungi.</p>
                </div>
            </div>
        </body>
        </html>
        HTML;
    }

    /**
     * Send WhatsApp reset notification via Fonnte
     */
    private function sendResetWhatsApp(Applicant $applicant, string $waBody): void
    {
        $fonnteKey = Setting::get('fonnte_api_key', config('services.fonnte.key'));
        if (!$fonnteKey || !$applicant->whatsapp) return;

        $message = strip_tags(str_replace(['<br>', '<br/>', '<br />'], "\n", $waBody));

        // Safety check: if variables are still unresolved, re-render
        if (preg_match('/\{(applicant_name|site_name|reset_url|email|site_url)\}/', $message)) {
            $siteName = Setting::get('site_name', config('app.name', 'Bursa Kerja'));
            $variables = [
                'applicant_name' => $applicant->name ?? 'Pelamar',
                'email' => $applicant->email ?? '',
                'reset_url' => '[link expired]',
                'site_name' => $siteName,
                'site_url' => config('app.url'),
            ];
            $message = MessageTemplate::render($message, $variables);
        }

        try {
            $response = Http::withHeaders([
                'Authorization' => $fonnteKey,
            ])->post('https://api.fonnte.com/send', [
                'target' => $applicant->whatsapp,
                'message' => $message,
                'countryCode' => '62',
            ]);

        } catch (\Exception $e) {
            Log::error('WhatsApp reset notification failed: ' . $e->getMessage());
        }
    }
}
