<?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use App\Http\Requests\Auth\LoginRequest;
use App\Services\ApiTokenService;
use App\Services\AuthService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Support\Facades\Auth;
use Illuminate\View\View;

class LoginController extends Controller
{
    public function __construct(
        private readonly AuthService $authService,
        private readonly ApiTokenService $apiTokenService
    ) {}

    /**
     * 로그인 폼 표시
     */
    public function showLoginForm(): View
    {
        return view('auth.login');
    }

    /**
     * 로그인 처리
     * - 이메일 또는 아이디로 로그인 가능
     * - 아이디 로그인은 본사 소속만 허용
     */
    public function login(LoginRequest $request): RedirectResponse
    {
        $credentials = $request->getCredentials();
        $loginField = $request->getLoginField();
        // Remember Me 항상 활성화 (세션 만료 시 자동 재인증 보장)
        $remember = true;

        if ($this->authService->login($credentials, $remember, $loginField)) {
            $request->session()->regenerate();

            return redirect()->intended('/dashboard')
                ->with('success', '로그인되었습니다.');
        }

        // AuthService에서 설정한 오류 메시지 사용
        $errorMessage = $this->authService->getLoginError()
            ?? '이메일/아이디 또는 비밀번호가 올바르지 않습니다.';

        return back()
            ->withErrors(['login' => $errorMessage])
            ->withInput($request->only('login'));
    }

    /**
     * 로그아웃 처리
     */
    public function logout(): RedirectResponse
    {
        $this->authService->logout();

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

        return redirect('/login')
            ->with('success', '로그아웃되었습니다.');
    }

    /**
     * 세션 갱신 (Remember Token으로 재인증)
     * HTMX 401 에러 시 호출되어 세션을 갱신합니다.
     */
    public function refreshSession(): JsonResponse
    {
        // 이미 인증된 경우 (세션이 아직 유효한 경우)
        if (Auth::check()) {
            return response()->json([
                'success' => true,
                'message' => '세션이 유효합니다.',
            ]);
        }

        // Remember Token으로 재인증 시도
        // Laravel의 Auth::viaRemember()는 remember token 쿠키로 인증 시도
        if (Auth::viaRemember()) {
            $user = Auth::user();

            // HQ 테넌트 소속 확인
            if (! $user->belongsToHQ()) {
                Auth::logout();

                return response()->json([
                    'success' => false,
                    'message' => '본사 소속 직원만 접근할 수 있습니다.',
                    'redirect' => '/login',
                ], 401);
            }

            // 활성 상태 확인
            if (! $user->is_active) {
                Auth::logout();

                return response()->json([
                    'success' => false,
                    'message' => '비활성화된 계정입니다.',
                    'redirect' => '/login',
                ], 401);
            }

            // HQ 테넌트를 기본 선택
            $hqTenant = $user->getHQTenant();
            if ($hqTenant) {
                session(['selected_tenant_id' => $hqTenant->id]);

                // API 토큰 재발급
                $this->refreshApiToken($user->id, $hqTenant->id);
            }

            return response()->json([
                'success' => true,
                'message' => '세션이 갱신되었습니다.',
            ]);
        }

        // Remember Token이 없거나 유효하지 않은 경우
        return response()->json([
            'success' => false,
            'message' => '세션이 만료되었습니다. 다시 로그인해주세요.',
            'redirect' => '/login',
        ], 401);
    }

    /**
     * API 토큰 재발급
     */
    private function refreshApiToken(int $userId, int $tenantId): void
    {
        try {
            $result = $this->apiTokenService->exchangeToken($userId, $tenantId);

            if ($result['success']) {
                $this->apiTokenService->storeTokenInSession(
                    $result['data']['access_token'],
                    $result['data']['expires_in']
                );
            }
        } catch (\Exception $e) {
            // API 토큰 재발급 실패해도 세션 갱신은 계속 진행
            \Log::warning('[LoginController] API token refresh failed', [
                'user_id' => $userId,
                'error' => $e->getMessage(),
            ]);
        }
    }
}
