import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:komet/backend/api.dart';
import 'package:komet/core/config/proxy_config.dart';
import 'package:komet/l10n/app_localizations.dart';

import '../../../main.dart';
import '../../widgets/custom_notification.dart';
import '../../widgets/labeled_settings_field.dart';
import '../../widgets/sheet_helpers.dart';

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

  @override
  State<ProxySettingsSheet> createState() => _ProxySettingsSheetState();
}

class _ProxySettingsSheetState extends State<ProxySettingsSheet> {
  final _hostController = TextEditingController();
  final _portController = TextEditingController(text: '1080');
  final _usernameController = TextEditingController();
  final _passwordController = TextEditingController();
  ProxyType _selectedType = ProxyType.none;
  bool _busy = false;

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

  Future<void> _load() async {
    final settings = await ProxyConfig.load();
    if (!mounted) return;
    setState(() {
      _selectedType = settings.type;
      _hostController.text = settings.host;
      _portController.text = '${settings.port}';
      _usernameController.text = settings.username ?? '';
      _passwordController.text = settings.password ?? '';
    });
  }

  Future<void> _apply(AppLocalizations l10n) async {
    if (_selectedType == ProxyType.none) {
      return _disable(l10n);
    }

    final host = _hostController.text.trim();
    final port = int.tryParse(_portController.text.trim());
    if (host.isEmpty || port == null || port < 1 || port > 65535) {
      showCustomNotification(context, l10n.proxyInvalidHostOrPort);
      return;
    }

    setState(() => _busy = true);
    try {
      final username = _usernameController.text.trim();
      final password = _passwordController.text.trim();
      await ProxyConfig.save(
        ProxySettings(
          type: _selectedType,
          host: host,
          port: port,
          username: username.isNotEmpty ? username : null,
          password: password.isNotEmpty ? password : null,
        ),
      );
      await api.disconnect();
      await api.connect();
      if (!mounted) return;
      if (api.state == SessionState.online) {
        showCustomNotification(context, l10n.proxySettingsSaved);
      } else {
        showCustomNotification(context, l10n.serverReconnectFailed);
      }
    } finally {
      if (mounted) setState(() => _busy = false);
    }
  }

  Future<void> _disable(AppLocalizations l10n) async {
    setState(() => _busy = true);
    try {
      await ProxyConfig.clear();
      setState(() => _selectedType = ProxyType.none);
      await api.disconnect();
      await api.connect();
      if (!mounted) return;
      if (api.state == SessionState.online) {
        showCustomNotification(context, l10n.proxySettingsSaved);
      } else {
        showCustomNotification(context, l10n.serverReconnectFailed);
      }
    } finally {
      if (mounted) setState(() => _busy = false);
    }
  }

  @override
  void dispose() {
    _hostController.dispose();
    _portController.dispose();
    _usernameController.dispose();
    _passwordController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    final cs = Theme.of(context).colorScheme;
    final l10n = AppLocalizations.of(context)!;
    final bottomInset = MediaQuery.viewInsetsOf(context).bottom;
    final isActive = _selectedType != ProxyType.none;

    return Padding(
      padding: EdgeInsets.only(bottom: bottomInset),
      child: SingleChildScrollView(
        child: Padding(
          padding: const EdgeInsets.fromLTRB(16, 8, 16, 24),
          child: Column(
            mainAxisSize: MainAxisSize.min,
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: [
              const Center(
                child: SheetGrabber(margin: EdgeInsets.only(bottom: 16)),
              ),
              Text(
                l10n.proxySettingsTitle,
                style: TextStyle(
                  color: cs.onSurface,
                  fontSize: 18,
                  fontWeight: FontWeight.w600,
                ),
              ),
              const SizedBox(height: 20),

              // Proxy type selector
              _buildTypeSelector(cs, l10n),
              const SizedBox(height: 16),

              // Fields shown only when proxy is enabled
              AnimatedSize(
                duration: const Duration(milliseconds: 200),
                curve: Curves.easeInOut,
                alignment: Alignment.topCenter,
                child: isActive
                    ? Column(
                        children: [
                          LabeledSettingsField(
                            controller: _hostController,
                            label: l10n.proxyHostLabel,
                            hintText: '127.0.0.1',
                            keyboardType: TextInputType.url,
                            enabled: !_busy,
                          ),
                          const SizedBox(height: 16),
                          LabeledSettingsField(
                            controller: _portController,
                            label: l10n.proxyPortLabel,
                            hintText: _selectedType == ProxyType.socks5
                                ? '1080'
                                : '8080',
                            keyboardType: TextInputType.number,
                            inputFormatters: [
                              FilteringTextInputFormatter.digitsOnly,
                            ],
                            enabled: !_busy,
                          ),
                          const SizedBox(height: 16),
                          LabeledSettingsField(
                            controller: _usernameController,
                            label: l10n.proxyUsernameLabel,
                            keyboardType: TextInputType.text,
                            enabled: !_busy,
                          ),
                          const SizedBox(height: 16),
                          LabeledSettingsField(
                            controller: _passwordController,
                            label: l10n.proxyPasswordLabel,
                            keyboardType: TextInputType.visiblePassword,
                            obscureText: true,
                            enabled: !_busy,
                          ),
                          const SizedBox(height: 8),
                        ],
                      )
                    : const SizedBox.shrink(),
              ),

              const SizedBox(height: 16),
              FilledButton(
                onPressed: _busy ? null : () => _apply(l10n),
                child: Text(isActive ? l10n.proxyApply : l10n.proxyDisable),
              ),
            ],
          ),
        ),
      ),
    );
  }

  Widget _buildTypeSelector(ColorScheme cs, AppLocalizations l10n) {
    final labels = {
      ProxyType.none: l10n.proxyTypeNone,
      ProxyType.socks5: l10n.proxyTypeSocks5,
      ProxyType.httpConnect: l10n.proxyTypeHttp,
    };

    return Container(
      decoration: BoxDecoration(
        color: cs.surfaceContainerHighest,
        borderRadius: BorderRadius.circular(12),
      ),
      padding: const EdgeInsets.all(4),
      child: Row(
        children: ProxyType.values.map((type) {
          final selected = _selectedType == type;
          return Expanded(
            child: GestureDetector(
              onTap: _busy ? null : () => setState(() => _selectedType = type),
              child: AnimatedContainer(
                duration: const Duration(milliseconds: 200),
                padding: const EdgeInsets.symmetric(vertical: 10),
                decoration: BoxDecoration(
                  color: selected ? cs.primary : Colors.transparent,
                  borderRadius: BorderRadius.circular(9),
                ),
                alignment: Alignment.center,
                child: Text(
                  labels[type]!,
                  style: TextStyle(
                    color: selected ? cs.onPrimary : cs.onSurfaceVariant,
                    fontSize: 13,
                    fontWeight: selected ? FontWeight.w600 : FontWeight.w500,
                  ),
                ),
              ),
            ),
          );
        }).toList(),
      ),
    );
  }
}
