part of '../../main.dart';

class UserSession {
  const UserSession({
    required this.id,
    required this.fullName,
    required this.username,
  });

  factory UserSession.fromJson(Map<String, dynamic> json) {
    return UserSession(
      id:
          json['id'] is int
              ? json['id'] as int
              : int.parse(json['id'].toString()),
      fullName: json['full_name']?.toString() ?? '',
      username: json['username']?.toString() ?? '',
    );
  }

  final int id;
  final String fullName;
  final String username;

  Map<String, dynamic> toJson() {
    return {'id': id, 'full_name': fullName, 'username': username};
  }
}

class AuthGate extends StatefulWidget {
  const AuthGate({super.key});

  @override
  State<AuthGate> createState() => _AuthGateState();
}

class _AuthGateState extends State<AuthGate> {
  static const _sessionPreferenceKey = 'confivoice_user_session';

  UserSession? _session;
  bool _isLoading = true;

  @override
  void initState() {
    super.initState();
    _loadSession();
  }

  Future<void> _loadSession() async {
    try {
      final preferences = await SharedPreferences.getInstance();
      final sessionJson = preferences.getString(_sessionPreferenceKey);
      if (sessionJson != null && sessionJson.isNotEmpty) {
        _session = UserSession.fromJson(
          (jsonDecode(sessionJson) as Map).cast<String, dynamic>(),
        );
      }
    } catch (_) {
      _session = null;
    }

    if (mounted) {
      setState(() {
        _isLoading = false;
      });
    }
  }

  Future<void> _setSession(UserSession session) async {
    final preferences = await SharedPreferences.getInstance();
    await preferences.setString(
      _sessionPreferenceKey,
      jsonEncode(session.toJson()),
    );
    if (mounted) {
      setState(() {
        _session = session;
      });
      WidgetsBinding.instance.addPostFrameCallback((_) {
        if (mounted) {
          showCompactSnackBar(
            context,
            message: 'Berhasil masuk, ${session.fullName}',
            icon: Icons.check_circle_outline,
          );
        }
      });
    }
  }

  Future<void> _logout() async {
    final preferences = await SharedPreferences.getInstance();
    await preferences.remove(_sessionPreferenceKey);
    if (mounted) {
      setState(() {
        _session = null;
      });
      WidgetsBinding.instance.addPostFrameCallback((_) {
        if (mounted) {
          showCompactSnackBar(context, message: 'Berhasil logout');
        }
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    if (_isLoading) {
      return const Scaffold(body: Center(child: CircularProgressIndicator()));
    }

    final session = _session;
    if (session == null) {
      return AuthPage(onAuthenticated: _setSession);
    }

    return ConfiVoiceShell(session: session, onLogout: _logout);
  }
}

class AuthPage extends StatefulWidget {
  const AuthPage({super.key, required this.onAuthenticated});

  final ValueChanged<UserSession> onAuthenticated;

  @override
  State<AuthPage> createState() => _AuthPageState();
}

class _AuthPageState extends State<AuthPage> {
  static const _apiEndpointPreferenceKey = 'confivoice_api_endpoint';

  final TextEditingController _apiController = TextEditingController(
    text: defaultApiEndpoint(),
  );
  final TextEditingController _fullNameController = TextEditingController();
  final TextEditingController _usernameController = TextEditingController();
  final TextEditingController _passwordController = TextEditingController();
  final TextEditingController _confirmPasswordController =
      TextEditingController();

  bool _isRegister = false;
  bool _isLoading = false;
  bool _obscurePassword = true;
  bool _obscureConfirmPassword = true;
  String? _errorMessage;

  @override
  void initState() {
    super.initState();
    _loadApiEndpoint();
  }

  @override
  void dispose() {
    _apiController.dispose();
    _fullNameController.dispose();
    _usernameController.dispose();
    _passwordController.dispose();
    _confirmPasswordController.dispose();
    super.dispose();
  }

  Future<void> _loadApiEndpoint() async {
    try {
      final preferences = await SharedPreferences.getInstance();
      final endpoint = normalizeApiEndpoint(
        preferences.getString(_apiEndpointPreferenceKey) ?? '',
      );
      if (endpoint.isNotEmpty && mounted) {
        setState(() {
          _apiController.text = endpoint;
        });
      }
    } catch (_) {}
  }

  Future<void> _saveApiEndpoint() async {
    final preferences = await SharedPreferences.getInstance();
    await preferences.setString(
      _apiEndpointPreferenceKey,
      _apiController.text.trim(),
    );
  }

  Uri? _authEndpoint(String path) {
    final predictEndpoint = Uri.tryParse(_apiController.text.trim());
    if (predictEndpoint == null ||
        !predictEndpoint.hasScheme ||
        predictEndpoint.host.isEmpty) {
      return null;
    }
    return predictEndpoint.replace(path: path, queryParameters: {});
  }

  Future<void> _submit() async {
    final endpoint = _authEndpoint(_isRegister ? '/register' : '/login');
    if (endpoint == null) {
      setState(() {
        _errorMessage = 'Endpoint API tidak valid.';
      });
      return;
    }

    final username = _usernameController.text.trim();
    final password = _passwordController.text;
    final confirmPassword = _confirmPasswordController.text;
    final fullName = _fullNameController.text.trim();
    if (username.isEmpty ||
        password.isEmpty ||
        (_isRegister && (fullName.isEmpty || confirmPassword.isEmpty))) {
      setState(() {
        _errorMessage = 'Lengkapi data akun terlebih dahulu.';
      });
      return;
    }

    if (_isRegister && password != confirmPassword) {
      setState(() {
        _errorMessage = 'Konfirmasi password belum sama.';
      });
      return;
    }

    setState(() {
      _isLoading = true;
      _errorMessage = null;
    });

    try {
      final body = <String, dynamic>{
        'username': username,
        'password': password,
        if (_isRegister) 'full_name': fullName,
      };
      final response = await http
          .post(
            endpoint,
            headers: {'Content-Type': 'application/json'},
            body: jsonEncode(body),
          )
          .timeout(const Duration(seconds: 30));

      if (response.statusCode < 200 || response.statusCode >= 300) {
        final decoded = jsonDecode(response.body);
        final detail =
            decoded is Map ? decoded['detail']?.toString() : response.body;
        throw Exception(detail ?? response.body);
      }

      await _saveApiEndpoint();
      if (_isRegister) {
        if (!mounted) {
          return;
        }
        final registeredUsername = username;
        setState(() {
          _isRegister = false;
          _fullNameController.clear();
          _usernameController.text = registeredUsername;
          _passwordController.clear();
          _confirmPasswordController.clear();
          _errorMessage = null;
        });
        showCompactSnackBar(
          context,
          message: 'Registrasi berhasil. Silakan login.',
          icon: Icons.check_circle_outline,
        );
        return;
      }

      final decoded = jsonDecode(response.body) as Map<String, dynamic>;
      final user = UserSession.fromJson(
        (decoded['user'] as Map).cast<String, dynamic>(),
      );
      widget.onAuthenticated(user);
    } catch (error) {
      setState(() {
        _errorMessage =
            _isRegister
                ? _cleanAuthErrorMessage(error)
                : 'Username atau password salah.';
      });
    } finally {
      if (mounted) {
        setState(() {
          _isLoading = false;
        });
      }
    }
  }

  String _cleanAuthErrorMessage(Object error) {
    final message = error.toString();
    const exceptionPrefix = 'Exception: ';
    return message.startsWith(exceptionPrefix)
        ? message.substring(exceptionPrefix.length)
        : message;
  }

  InputDecoration _authFieldDecoration({
    required String label,
    required IconData icon,
    Widget? suffixIcon,
  }) {
    return InputDecoration(
      filled: true,
      fillColor: Colors.white,
      labelText: label,
      labelStyle: const TextStyle(color: Color(0xFF536179)),
      prefixIcon: Icon(icon, color: AppColors.navy, size: 20),
      suffixIcon: suffixIcon,
      contentPadding: const EdgeInsets.symmetric(horizontal: 14, vertical: 14),
      enabledBorder: OutlineInputBorder(
        borderRadius: BorderRadius.circular(12),
        borderSide: const BorderSide(color: Color(0xFFD8DFEA)),
      ),
      focusedBorder: OutlineInputBorder(
        borderRadius: BorderRadius.circular(12),
        borderSide: const BorderSide(color: AppColors.blue, width: 1.5),
      ),
      errorBorder: OutlineInputBorder(
        borderRadius: BorderRadius.circular(12),
        borderSide: const BorderSide(color: AppColors.recording),
      ),
      focusedErrorBorder: OutlineInputBorder(
        borderRadius: BorderRadius.circular(12),
        borderSide: const BorderSide(color: AppColors.recording),
      ),
    );
  }

  Widget _buildModeSwitch() {
    return Container(
      height: 46,
      padding: const EdgeInsets.all(4),
      decoration: BoxDecoration(
        color: const Color(0xFFEAF2FF),
        borderRadius: BorderRadius.circular(14),
        border: Border.all(color: const Color(0xFFD6E3F7)),
      ),
      child: Stack(
        children: [
          AnimatedAlign(
            duration: const Duration(milliseconds: 260),
            curve: Curves.easeOutCubic,
            alignment:
                _isRegister ? Alignment.centerRight : Alignment.centerLeft,
            child: FractionallySizedBox(
              widthFactor: 0.5,
              child: Container(
                decoration: BoxDecoration(
                  gradient: const LinearGradient(
                    colors: [Color(0xFF0D2A52), Color(0xFF2563EB)],
                  ),
                  borderRadius: BorderRadius.circular(10),
                  boxShadow: [
                    BoxShadow(
                      color: const Color(0xFF102A56).withValues(alpha: 0.22),
                      blurRadius: 12,
                      offset: const Offset(0, 6),
                    ),
                  ],
                ),
              ),
            ),
          ),
          Row(
            children: [
              _ModeButton(
                label: 'Masuk',
                isSelected: !_isRegister,
                onTap: () {
                  setState(() {
                    _isRegister = false;
                    _errorMessage = null;
                    _confirmPasswordController.clear();
                  });
                },
              ),
              _ModeButton(
                label: 'Daftar',
                isSelected: _isRegister,
                onTap: () {
                  setState(() {
                    _isRegister = true;
                    _errorMessage = null;
                  });
                },
              ),
            ],
          ),
        ],
      ),
    );
  }

  Widget _buildAuthForm() {
    return SizedBox(
      height: 270,
      child: AnimatedSwitcher(
        duration: const Duration(milliseconds: 260),
        transitionBuilder: (child, animation) {
          final offset = Tween<Offset>(
            begin: Offset(_isRegister ? 0.10 : -0.10, 0),
            end: Offset.zero,
          ).animate(CurvedAnimation(parent: animation, curve: Curves.easeOut));
          return FadeTransition(
            opacity: animation,
            child: SlideTransition(position: offset, child: child),
          );
        },
        child:
            _isRegister
                ? Column(
                  key: const ValueKey('register-form'),
                  children: [
                    TextField(
                      controller: _fullNameController,
                      style: const TextStyle(color: Color(0xFF0F172A)),
                      decoration: _authFieldDecoration(
                        label: 'Nama lengkap',
                        icon: Icons.badge_outlined,
                      ),
                      textInputAction: TextInputAction.next,
                    ),
                    const SizedBox(height: 12),
                    TextField(
                      controller: _usernameController,
                      style: const TextStyle(color: Color(0xFF0F172A)),
                      decoration: _authFieldDecoration(
                        label: 'Username',
                        icon: Icons.person_outline,
                      ),
                      textInputAction: TextInputAction.next,
                    ),
                    const SizedBox(height: 12),
                    _PasswordField(
                      controller: _passwordController,
                      obscureText: _obscurePassword,
                      label: 'Password',
                      icon: Icons.lock_outline,
                      onToggle: () {
                        setState(() {
                          _obscurePassword = !_obscurePassword;
                        });
                      },
                      onSubmitted: (_) => _submit(),
                      decorationBuilder: _authFieldDecoration,
                    ),
                    const SizedBox(height: 12),
                    _PasswordField(
                      controller: _confirmPasswordController,
                      obscureText: _obscureConfirmPassword,
                      label: 'Konfirmasi password',
                      icon: Icons.lock_reset_outlined,
                      onToggle: () {
                        setState(() {
                          _obscureConfirmPassword = !_obscureConfirmPassword;
                        });
                      },
                      onSubmitted: (_) => _submit(),
                      decorationBuilder: _authFieldDecoration,
                    ),
                  ],
                )
                : Column(
                  key: const ValueKey('login-form'),
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    TextField(
                      controller: _usernameController,
                      style: const TextStyle(color: Color(0xFF0F172A)),
                      decoration: _authFieldDecoration(
                        label: 'Username',
                        icon: Icons.person_outline,
                      ),
                      textInputAction: TextInputAction.next,
                    ),
                    const SizedBox(height: 12),
                    _PasswordField(
                      controller: _passwordController,
                      obscureText: _obscurePassword,
                      label: 'Password',
                      icon: Icons.lock_outline,
                      onToggle: () {
                        setState(() {
                          _obscurePassword = !_obscurePassword;
                        });
                      },
                      onSubmitted: (_) => _submit(),
                      decorationBuilder: _authFieldDecoration,
                    ),
                  ],
                ),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        decoration: const BoxDecoration(
          gradient: LinearGradient(
            begin: Alignment.topCenter,
            end: Alignment.bottomCenter,
            colors: [Color(0xFF081A33), Color(0xFF0F3A6D), Color(0xFF5EB2F7)],
          ),
        ),
        child: SafeArea(
          child: Center(
            child: SingleChildScrollView(
              padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 28),
              child: ConstrainedBox(
                constraints: const BoxConstraints(maxWidth: 420),
                child: Column(
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    const Icon(
                      Icons.graphic_eq_rounded,
                      color: Colors.white,
                      size: 42,
                    ),
                    const SizedBox(height: 10),
                    const Text(
                      'Confivoice',
                      style: TextStyle(
                        color: Colors.white,
                        fontSize: 30,
                        fontWeight: FontWeight.w800,
                        letterSpacing: 0.2,
                      ),
                    ),
                    const SizedBox(height: 26),
                    Container(
                      padding: const EdgeInsets.all(18),
                      decoration: BoxDecoration(
                        color: Colors.white,
                        borderRadius: BorderRadius.circular(20),
                        border: Border.all(color: const Color(0xFFE2E8F0)),
                        boxShadow: [
                          BoxShadow(
                            color: Colors.black.withValues(alpha: 0.20),
                            blurRadius: 28,
                            offset: const Offset(0, 18),
                          ),
                        ],
                      ),
                      child: Column(
                        crossAxisAlignment: CrossAxisAlignment.stretch,
                        children: [
                          _buildModeSwitch(),
                          const SizedBox(height: 22),
                          _buildAuthForm(),
                          const SizedBox(height: 18),
                          SizedBox(
                            height: 50,
                            child: FilledButton(
                              onPressed: _isLoading ? null : _submit,
                              style: FilledButton.styleFrom(
                                backgroundColor: AppColors.navy,
                                foregroundColor: Colors.white,
                                shape: RoundedRectangleBorder(
                                  borderRadius: BorderRadius.circular(14),
                                ),
                              ),
                              child:
                                  _isLoading
                                      ? const SizedBox.square(
                                        dimension: 20,
                                        child: CircularProgressIndicator(
                                          strokeWidth: 2.2,
                                          color: Colors.white,
                                        ),
                                      )
                                      : Text(
                                        _isRegister ? 'Daftar' : 'Masuk',
                                        style: const TextStyle(
                                          fontSize: 16,
                                          fontWeight: FontWeight.w800,
                                        ),
                                      ),
                            ),
                          ),
                          if (_errorMessage != null) ...[
                            const SizedBox(height: 12),
                            _AuthErrorBox(message: _errorMessage!),
                          ],
                        ],
                      ),
                    ),
                  ],
                ),
              ),
            ),
          ),
        ),
      ),
    );
  }
}

class _ModeButton extends StatelessWidget {
  const _ModeButton({
    required this.label,
    required this.isSelected,
    required this.onTap,
  });

  final String label;
  final bool isSelected;
  final VoidCallback onTap;

  @override
  Widget build(BuildContext context) {
    return Expanded(
      child: InkWell(
        borderRadius: BorderRadius.circular(10),
        onTap: onTap,
        child: Center(
          child: AnimatedDefaultTextStyle(
            duration: const Duration(milliseconds: 180),
            style: TextStyle(
              color: isSelected ? Colors.white : const Color(0xFF0F172A),
              fontSize: 16,
              fontWeight: FontWeight.w800,
            ),
            child: Text(label),
          ),
        ),
      ),
    );
  }
}

class _PasswordField extends StatelessWidget {
  const _PasswordField({
    required this.controller,
    required this.obscureText,
    required this.label,
    required this.icon,
    required this.onToggle,
    required this.onSubmitted,
    required this.decorationBuilder,
  });

  final TextEditingController controller;
  final bool obscureText;
  final String label;
  final IconData icon;
  final VoidCallback onToggle;
  final ValueChanged<String> onSubmitted;
  final InputDecoration Function({
    required String label,
    required IconData icon,
    Widget? suffixIcon,
  })
  decorationBuilder;

  @override
  Widget build(BuildContext context) {
    return TextField(
      controller: controller,
      obscureText: obscureText,
      style: const TextStyle(color: Color(0xFF0F172A)),
      decoration: decorationBuilder(
        label: label,
        icon: icon,
        suffixIcon: IconButton(
          tooltip: obscureText ? 'Tampilkan password' : 'Sembunyikan password',
          onPressed: onToggle,
          icon: Icon(
            obscureText
                ? Icons.visibility_outlined
                : Icons.visibility_off_outlined,
            color: AppColors.navy,
          ),
        ),
      ),
      onSubmitted: onSubmitted,
    );
  }
}

class _AuthErrorBox extends StatelessWidget {
  const _AuthErrorBox({required this.message});

  final String message;

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: const EdgeInsets.all(12),
      decoration: BoxDecoration(
        color: const Color(0xFFFFF7ED),
        borderRadius: BorderRadius.circular(12),
        border: Border.all(color: const Color(0xFFFBBF24)),
      ),
      child: Text(
        message,
        style: const TextStyle(color: Color(0xFF92400E), fontSize: 12),
      ),
    );
  }
}

// create a login form with email and password validation
