<?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Support\Str;
use Illuminate\Validation\ValidationException;

class LoginController extends Controller
{
    /**
     * ログイン成功後のリダイレクト先
     *
     * @var string
     */
    protected $redirectTo = '/home';

    /**
     * コントローラーのインスタンス作成
     * Laravel 12変更点：ミドルウェアは routes/web.php で処理するように変更
     *
     * @return void
     */
    public function __construct()
    {
        // Laravel 12: ミドルウェアは routes/web.php で処理
        // Laravel 5.7: $this->middleware('guest')->except('logout'); を使用していた
    }

    /**
     * ログインフォームを表示
     *
     * @return \Illuminate\View\View
     */
    public function showLoginForm()
    {
        return view('auth.login');
    }

    /**
     * ログインリクエストを処理
     * Laravel 12変更点：AuthenticatesUsersトレイトを使わず独自実装
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\Response|\Illuminate\Http\JsonResponse
     */
    public function login(Request $request)
    {
        $this->validateLogin($request);

        // ログイン試行回数制限チェック
        if ($this->hasTooManyLoginAttempts($request)) {
            $this->fireLockoutEvent($request);
            return $this->sendLockoutResponse($request);
        }

        // ログイン認証試行
        if ($this->attemptLogin($request)) {
            return $this->sendLoginResponse($request);
        }

        // ログイン失敗時の処理
        $this->incrementLoginAttempts($request);

        return $this->sendFailedLoginResponse($request);
    }

    /**
     * ログインリクエストのバリデーション
     * Laravel 12変更点：ope_id, ope_passフィールドを使用（Laravel 5.7と同じ）
     *
     * @param  \Illuminate\Http\Request  $request
     * @return void
     */
    protected function validateLogin(Request $request)
    {
        $request->validate([
            'ope_id' => 'required|string',     // オペレータID（旧システムと同じ）
            'ope_pass' => 'required|string',   // オペレータパスワード（旧システムと同じ）
        ]);
    }

    /**
     * ログイン認証を試行
     *
     * @param  \Illuminate\Http\Request  $request
     * @return bool
     */
    protected function attemptLogin(Request $request)
    {
        return Auth::attempt($this->credentials($request), false);
    }

    /**
     * 認証用の資格情報を取得
     * Laravel 12変更点：ope_idとope_passをpasswordフィールドにマッピング
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    protected function credentials(Request $request)
    {
        // Laravel 5.7: ope_id, ope_passをそのまま使用
        // Laravel 12: ope_passをpasswordにマッピングして認証
        return $request->only('ope_id') + ['password' => $request->input('ope_pass')];
    }

    
    /**
     * ログイン成功時のレスポンス
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\JsonResponse
     */
    protected function sendLoginResponse(Request $request)
    {
        $request->session()->regenerate();

        $this->clearLoginAttempts($request);

        return redirect()->intended($this->redirectTo);
    }

    /**
     * ログイン失敗時のレスポンス
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\RedirectResponse
     */
    protected function sendFailedLoginResponse(Request $request)
    {
        throw ValidationException::withMessages([
            'ope_id' => [trans('auth.failed')],
        ]);
    }

    /**
     * ログアウト処理
     * Laravel 12変更点：セッション無効化処理を追加
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\JsonResponse
     */
    public function logout(Request $request)
    {
        Auth::logout();

        // Laravel 12: セッション無効化とトークン再生成を明示的に実行
        $request->session()->invalidate();
        $request->session()->regenerateToken();

        return redirect('/login');
    }

    /**
     * ログイン試行回数が上限を超えているかチェック
     * Laravel 12変更点：RateLimiterファサードを使用
     *
     * @param  \Illuminate\Http\Request  $request
     * @return bool
     */
    protected function hasTooManyLoginAttempts(Request $request)
    {
        return RateLimiter::tooManyAttempts(
            $this->throttleKey($request), 5
        );
    }

    /**
     * ログイン試行回数をインクリメント
     *
     * @param  \Illuminate\Http\Request  $request
     * @return void
     */
    protected function incrementLoginAttempts(Request $request)
    {
        RateLimiter::hit(
            $this->throttleKey($request), 60
        );
    }

    /**
     * ログイン試行回数制限をクリア
     *
     * @param  \Illuminate\Http\Request  $request
     * @return void
     */
    protected function clearLoginAttempts(Request $request)
    {
        RateLimiter::clear($this->throttleKey($request));
    }

    /**
     * ロックアウト発生時のイベント処理
     *
     * @param  \Illuminate\Http\Request  $request
     * @return void
     */
    protected function fireLockoutEvent(Request $request)
    {
        // 必要に応じてイベントを発火
    }

    /**
     * レート制限用のスロットルキーを取得
     *
     * @param  \Illuminate\Http\Request  $request
     * @return string
     */
    protected function throttleKey(Request $request)
    {
        return Str::lower($request->input('ope_id')).'|'.$request->ip();
    }

    /**
     * ロックアウト時のレスポンス
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\RedirectResponse
     */
    protected function sendLockoutResponse(Request $request)
    {
        $seconds = RateLimiter::availableIn(
            $this->throttleKey($request)
        );

        throw ValidationException::withMessages([
            'ope_id' => [trans('auth.throttle', ['seconds' => $seconds])],
        ]);
    }
} 