import 'dart:math' as math;

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:get_it/get_it.dart';
import 'package:go_router/go_router.dart';
import 'package:shadcn_ui/shadcn_ui.dart';

import '../../../../core/constants/app_sections.dart';
import '../../../../core/network/api_error.dart';
import '../../../../core/network/failure.dart';
import '../../../../core/permissions/permission_bootstrapper.dart';
import '../../../../core/permissions/permission_manager.dart';
import '../../../auth/application/auth_service.dart';
import '../../../auth/domain/entities/auth_session.dart';
import '../../../auth/domain/entities/login_request.dart';
import '../../../masters/group/domain/repositories/group_repository.dart';
import '../../../masters/group_permission/domain/repositories/group_permission_repository.dart';

/// Superport 로그인 화면. 간단한 유효성 검증 후 대시보드로 이동한다.
class LoginPage extends StatefulWidget {
  const LoginPage({super.key});

  @override
  State<LoginPage> createState() => _LoginPageState();
}

/// 로그인 폼의 상태를 관리한다.
class _LoginPageState extends State<LoginPage> {
  final idController = TextEditingController();
  final passwordController = TextEditingController();
  bool rememberMe = false;
  bool isLoading = false;
  String? errorMessage;

  @override
  void dispose() {
    idController.dispose();
    passwordController.dispose();
    super.dispose();
  }

  Future<void> _handleSubmit() async {
    if (isLoading) return;
    setState(() {
      errorMessage = null;
      isLoading = true;
    });

    final id = idController.text.trim();
    final password = passwordController.text.trim();

    if (id.isEmpty || password.isEmpty) {
      setState(() {
        errorMessage = '아이디와 비밀번호를 모두 입력하세요.';
        isLoading = false;
      });
      return;
    }

    if (password.length < 6) {
      setState(() {
        errorMessage = '비밀번호는 6자 이상이어야 합니다.';
        isLoading = false;
      });
      return;
    }

    final authService = GetIt.I<AuthService>();
    AuthSession? session;

    if (!mounted) return;
    try {
      session = await authService.login(
        LoginRequest(
          identifier: id,
          password: password,
          rememberMe: rememberMe,
        ),
      );
      await _applyPermissions(session);
    } catch (error) {
      if (!mounted) return;
      final failure = Failure.from(error);
      final description = failure.describe();
      final hasApiDetails = failure.raw is ApiException;
      final message = hasApiDetails && description.isNotEmpty
          ? description
          : '권한 정보를 불러오지 못했습니다. 잠시 후 다시 시도하세요.';
      setState(() {
        errorMessage = message;
        isLoading = false;
      });
      return;
    }

    if (!mounted) return;
    setState(() => isLoading = false);
    context.go(dashboardRoutePath);
  }

  @override
  Widget build(BuildContext context) {
    final theme = ShadTheme.of(context);

    return Scaffold(
      backgroundColor: theme.colorScheme.background,
      body: SafeArea(
        child: Center(
          child: SingleChildScrollView(
            padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 40),
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                _buildHeader(theme),
                const SizedBox(height: 32),
                ConstrainedBox(
                  constraints: const BoxConstraints(maxWidth: 460),
                  child: _buildLoginCard(theme),
                ),
                const SizedBox(height: 24),
                _buildFooter(theme),
              ],
            ),
          ),
        ),
      ),
    );
  }

  /// 로그인 헤더에 브랜드 아이콘과 안내 문구를 배치한다.
  Widget _buildHeader(ShadThemeData theme) {
    return Column(
      children: [
        DecoratedBox(
          decoration: BoxDecoration(
            shape: BoxShape.circle,
            gradient: LinearGradient(
              colors: [
                theme.colorScheme.primary,
                theme.colorScheme.primary.withValues(alpha: 0.8),
                theme.colorScheme.primary.withValues(alpha: 0.6),
              ],
              begin: Alignment.topLeft,
              end: Alignment.bottomRight,
            ),
            boxShadow: [
              BoxShadow(
                color: theme.colorScheme.primary.withValues(alpha: 0.3),
                blurRadius: 24,
                offset: const Offset(0, 12),
              ),
            ],
          ),
          child: Padding(
            padding: const EdgeInsets.all(20),
            child: TweenAnimationBuilder<double>(
              duration: const Duration(milliseconds: 1400),
              tween: Tween(begin: 0, end: 1),
              curve: Curves.easeInOut,
              builder: (context, value, child) {
                return Transform.rotate(
                  angle: value * 2 * math.pi * 0.08,
                  child: child,
                );
              },
              child: Icon(
                LucideIcons.ship,
                size: 48,
                color: theme.colorScheme.primaryForeground,
              ),
            ),
          ),
        ),
        const SizedBox(height: 24),
        Text(
          'Superport v2',
          style: theme.textTheme.h2.copyWith(
            foreground: Paint()
              ..shader = LinearGradient(
                colors: [
                  theme.colorScheme.primary,
                  theme.colorScheme.primary.withValues(alpha: 0.7),
                ],
              ).createShader(const Rect.fromLTWH(0, 0, 220, 80)),
          ),
        ),
        const SizedBox(height: 8),
        Text(
          '포트 운영 전용 스마트 ERP',
          style: theme.textTheme.muted,
          textAlign: TextAlign.center,
        ),
      ],
    );
  }

  /// 로그인 폼 카드 레이아웃을 구성한다.
  Widget _buildLoginCard(ShadThemeData theme) {
    return ShadCard(
      title: Text('Superport v2 로그인', style: theme.textTheme.h3),
      description: Text(
        '사번 또는 이메일과 비밀번호를 입력하여 대시보드로 이동합니다.',
        style: theme.textTheme.muted,
      ),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.stretch,
        children: [
          ShadInput(
            controller: idController,
            placeholder: const Text('사번 또는 이메일'),
            autofillHints: const [AutofillHints.username],
            leading: const Icon(LucideIcons.user),
          ),
          const SizedBox(height: 16),
          ShadInput(
            controller: passwordController,
            placeholder: const Text('비밀번호'),
            obscureText: true,
            autofillHints: const [AutofillHints.password],
            leading: const Icon(LucideIcons.lock),
          ),
          const SizedBox(height: 12),
          Row(
            children: [
              ShadSwitch(
                value: rememberMe,
                onChanged: (value) => setState(() => rememberMe = value),
              ),
              const SizedBox(width: 12),
              Text('자동 로그인', style: theme.textTheme.small),
            ],
          ),
          const SizedBox(height: 24),
          if (errorMessage != null)
            Padding(
              padding: const EdgeInsets.only(bottom: 12),
              child: Text(
                errorMessage!,
                style: theme.textTheme.small.copyWith(
                  color: theme.colorScheme.destructive,
                ),
              ),
            ),
          ShadButton(
            onPressed: isLoading ? null : _handleSubmit,
            child: Row(
              mainAxisAlignment: MainAxisAlignment.center,
              mainAxisSize: MainAxisSize.min,
              children: [
                if (isLoading) ...[
                  const SizedBox(
                    width: 16,
                    height: 16,
                    child: CircularProgressIndicator(strokeWidth: 2),
                  ),
                  const SizedBox(width: 8),
                ],
                const Text('로그인'),
              ],
            ),
          ),
          if (kDebugMode) ...[
            const SizedBox(height: 12),
            // QA 요청: 디버그 로그인 버튼을 테마 색상과 굵은 서체로 강조하여 피드백 반영.
            ShadButton.ghost(
              onPressed: isLoading ? null : _handleTeraLogin,
              child: Text(
                'tera로그인',
                style: theme.textTheme.small.copyWith(
                  color: theme.colorScheme.primary,
                  fontWeight: FontWeight.w600,
                ),
              ),
            ),
            const SizedBox(height: 8),
            ShadButton.ghost(
              onPressed: isLoading ? null : _handleExaLogin,
              child: Text(
                'exa로그인',
                style: theme.textTheme.small.copyWith(
                  color: theme.colorScheme.primary,
                  fontWeight: FontWeight.w600,
                ),
              ),
            ),
          ],
        ],
      ),
    );
  }

  /// 로그인 하단에 간단한 안내 메시지를 노출한다.
  Widget _buildFooter(ShadThemeData theme) {
    return Column(
      children: [
        Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: const [
            Icon(LucideIcons.packagePlus, size: 18),
            SizedBox(width: 12),
            Icon(LucideIcons.packageMinus, size: 18),
            SizedBox(width: 12),
            Icon(LucideIcons.handshake, size: 18),
          ],
        ),
        const SizedBox(height: 16),
        Text(
          '입고 · 출고 · 대여 전 과정을 한 곳에서 관리하세요.',
          style: theme.textTheme.small,
          textAlign: TextAlign.center,
        ),
      ],
    );
  }

  /// 디버그 모드에서 테라(Tera) 계정으로 실서버 로그인한다.
  void _handleTeraLogin() {
    if (isLoading) {
      return;
    }

    const teraIdentifier = 'terabits';
    const teraPassword = '123456';

    idController.text = teraIdentifier;
    passwordController.text = teraPassword;

    setState(() {
      rememberMe = false;
      errorMessage = null;
    });

    _handleSubmit();
  }

  /// 디버그 모드에서 엑사(Exa) 계정으로 실서버 로그인한다.
  void _handleExaLogin() {
    if (isLoading) {
      return;
    }

    const exaIdentifier = 'exabits';
    const exaPassword = '123456';

    idController.text = exaIdentifier;
    passwordController.text = exaPassword;

    setState(() {
      rememberMe = false;
      errorMessage = null;
    });

    _handleSubmit();
  }

  Future<void> _applyPermissions(AuthSession session) async {
    final bootstrapper = PermissionBootstrapper(
      manager: PermissionScope.of(context),
      groupRepository: GetIt.I<GroupRepository>(),
      groupPermissionRepository: GetIt.I<GroupPermissionRepository>(),
    );
    await bootstrapper.apply(session);
  }
}
