<?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use App\Mail\EmailOtpMail;
use App\Models\Ope;
use App\Services\EmailOtpService;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Mail;

/**
 * OTP メール認証コントローラー
 * 
 * ログイン後の OTP（ワンタイムパスワード）検証プロセスを処理します
 */
class EmailOtpController extends Controller
{
    use ValidatesRequests;

    protected EmailOtpService $otpService;

    /**
     * コンストラクタ
     */
    public function __construct(EmailOtpService $otpService)
    {
        $this->otpService = $otpService;
    }

    /**
     * OTP 入力フォームを表示
     * 
     * ログイン直後、ユーザーに6桁の OTP コードを入力させるページを表示します
     * メールアドレスはマスク表示（例：a***@example.com）
     */
    public function show(Request $request)
    {
        /** @var Ope */
        $user = $request->user();

        // メールアドレスをマスク（最初の1文字のみ表示）
        $maskedEmail = $this->otpService->maskEmail($user->ope_mail);

        // 次の重発までの待機時間
        $resendWaitSeconds = $this->otpService->getResendWaitSeconds($user);

        return view('auth.otp', [
            'maskedEmail' => $maskedEmail,
            'resendWaitSeconds' => $resendWaitSeconds,
        ]);
    }

    /**
     * OTP コード検証
     * 
     * ユーザーが入力した6桁のコードを検証します
     * 
     * 成功時：email_otp_verified_at を更新し、ホームページにリダイレクト
     * 失敗時：エラーメッセージと共に OTP 入力フォームに戻す
     */
    public function verify(Request $request)
    {
        // 入力値を検証
        $validated = $this->validate($request, [
            'code' => ['required', 'string', 'size:6', 'regex:/^\d{6}$/'],
        ], [
            'code.required' => 'OTPコードは必須です。',
            'code.size' => 'OTPコードは6桁である必要があります。',
            'code.regex' => 'OTPコードは6桁の数字である必要があります。',
        ]);

        /** @var Ope */
        $user = $request->user();

        // OTP コードを検証
        if ($this->otpService->verify($user, $validated['code'])) {
            // 検証成功：ホームページにリダイレクト
            return redirect()->intended(route('home'))
                ->with('success', 'OTP認証が完了しました。');
        }

        // 検証失敗：エラーメッセージと共に戻す
        return back()
            ->withInput()
            ->with('error', '無効なまたは有効期限切れのOTPコードです。');
    }

    /**
     * OTP コード再送
     * 
     * ユーザーが OTP コード再送をリクエストした場合に実行
     * 60秒以内の連続再送はブロックします
     */
    public function resend(Request $request)
    {
        /** @var Ope */
        $user = $request->user();

        // 重発可能か確認
        if (!$this->otpService->canResend($user)) {
            $waitSeconds = $this->otpService->getResendWaitSeconds($user);
            
            return back()->with('error', "後 {$waitSeconds} 秒待機してからリクエストしてください。");
        }

        try {
            // 新しい OTP コードを発行
            $otpCode = $this->otpService->issue($user);

            // ope_mail はセミコロン区切りで複数アドレスを保持する可能性があるため、最初のアドレスのみ抽出
            $operatorEmails = explode(';', trim($user->ope_mail));
            $primaryEmail = trim($operatorEmails[0] ?? $user->ope_mail);

            Log::info('OTP 再送メール送信開始: ' . $primaryEmail);
            
            // メール送信
            Mail::to($primaryEmail)->send(new EmailOtpMail(
                $otpCode,
                $user->name ?? 'ユーザー'
            ));

            Log::info('OTP 再送メール送信完了: ' . $primaryEmail);

            return back()->with('success', 'OTPコードを再送信しました。');
        } catch (\Exception $e) {
            Log::error('OTP resend error: ' . $e->getMessage(), [
                'exception' => $e,
                'user_id' => $user->ope_id ?? null,
                'user_email' => $user->ope_mail ?? null,
            ]);
            
            return back()->with('error', 'OTP送信に失敗しました。もう一度お試しください。');
        }
    }
}
