

import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:file_picker/file_picker.dart';
import 'package:image_picker/image_picker.dart';
import 'package:mobile_scanner/mobile_scanner.dart';
import 'package:shared_preferences/shared_preferences.dart';


import 'package:gwid/api/api_service.dart';
import 'package:gwid/home_screen.dart';
import 'package:gwid/proxy_service.dart';
import 'package:gwid/proxy_settings.dart';
import 'package:gwid/screens/settings/qr_scanner_screen.dart';
import 'package:gwid/screens/settings/session_spoofing_screen.dart';


import 'package:encrypt/encrypt.dart' as encrypt;
import 'package:crypto/crypto.dart' as crypto;

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

  @override
  State<TokenAuthScreen> createState() => _TokenAuthScreenState();
}

class _TokenAuthScreenState extends State<TokenAuthScreen> {
  final TextEditingController _tokenController = TextEditingController();
  bool _isLoading = false;

  @override
  void dispose() {
    _tokenController.dispose();
    super.dispose();
  }


  Future<void> _processLogin({
    required String token,
    Map<String, dynamic>? spoofData,
    ProxySettings? proxySettings,
  }) async {
    if (!mounted) return;
    setState(() => _isLoading = true);
    final messenger = ScaffoldMessenger.of(context);

    try {
      if (spoofData != null && spoofData.isNotEmpty) {

        messenger.showSnackBar(
          const SnackBar(
            content: Text('Настройки анонимности из файла применены!'),
          ),
        );
      }
      if (proxySettings != null) {
        await ProxyService.instance.saveProxySettings(proxySettings);
        messenger.showSnackBar(
          const SnackBar(
            content: Text('Настройки прокси из файла применены!'),
            backgroundColor: Colors.blue,
          ),
        );
      }

      await ApiService.instance.saveToken(token);

      if (mounted) {
        Navigator.of(context).pushAndRemoveUntil(
          MaterialPageRoute(builder: (context) => const HomeScreen()),
          (Route<dynamic> route) => false,
        );
      }
    } catch (e) {
      messenger.showSnackBar(
        SnackBar(
          content: Text('Ошибка входа: ${e.toString()}'),
          backgroundColor: Colors.red,
        ),
      );
    } finally {
      if (mounted) setState(() => _isLoading = false);
    }
  }



  void _loginWithToken() {
    final token = _tokenController.text.trim();
    if (token.isEmpty) {
      ScaffoldMessenger.of(
        context,
      ).showSnackBar(const SnackBar(content: Text('Введите токен для входа')));
      return;
    }
    _processLogin(token: token);
  }

  Future<void> _loadSessionFile() async {

    FilePickerResult? result = await FilePicker.platform.pickFiles(
      type: FileType.custom,
      allowedExtensions: ['json','ksession'],
    );
    if (result == null || result.files.single.path == null) return;
    final filePath = result.files.single.path!;
    setState(() => _isLoading = true);
    try {
      final fileContent = await File(filePath).readAsString();
      Map<String, dynamic> jsonData = json.decode(fileContent);
      String finalJsonPayload;
      if (jsonData['encrypted'] == true) {
        final password = await _showPasswordDialog();
        if (password == null || password.isEmpty) {
          setState(() => _isLoading = false);
          return;
        }
        final iv = encrypt.IV.fromBase64(jsonData['iv_base64']);
        final encryptedData = encrypt.Encrypted.fromBase64(
          jsonData['data_base64'],
        );
        final keyBytes = utf8.encode(password);
        final keyHash = crypto.sha256.convert(keyBytes);
        final key = encrypt.Key(Uint8List.fromList(keyHash.bytes));
        final encrypter = encrypt.Encrypter(
          encrypt.AES(key, mode: encrypt.AESMode.cbc),
        );
        finalJsonPayload = encrypter.decrypt(encryptedData, iv: iv);
      } else {
        finalJsonPayload = fileContent;
      }
      final Map<String, dynamic> sessionData = json.decode(finalJsonPayload);
      final String? token = sessionData['token'];
      if (token == null || token.isEmpty)
        throw Exception('Файл сессии не содержит токена.');
      await _processLogin(
        token: token,
        spoofData: sessionData['spoof_data'] is Map<String, dynamic>
            ? sessionData['spoof_data']
            : null,
        proxySettings: sessionData['proxy_settings'] is Map<String, dynamic>
            ? ProxySettings.fromJson(sessionData['proxy_settings'])
            : null,
      );
    } catch (e) {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('Ошибка: $e'), backgroundColor: Colors.red),
      );
      setState(() => _isLoading = false);
    }
  }

  Future<void> _processQrData(String qrData) async {

    if (!mounted) return;
    setState(() => _isLoading = true);
    final messenger = ScaffoldMessenger.of(context);

    try {
      final decoded = jsonDecode(qrData) as Map<String, dynamic>;


      if (decoded['type'] != 'komet_auth_v1' ||
          decoded['token'] == null ||
          decoded['timestamp'] == null) {
        throw Exception("Неверный формат QR-кода.");
      }


      final int qrTimestamp = decoded['timestamp'];
      final String token = decoded['token'];


      final int now = DateTime.now().millisecondsSinceEpoch;
      const int oneMinuteInMillis = 60 * 1000; // 60 секунд

      if ((now - qrTimestamp) > oneMinuteInMillis) {

        throw Exception("QR-код устарел. Пожалуйста, сгенерируйте новый.");
      }


      await _processLogin(token: token);
    } catch (e) {
      messenger.showSnackBar(
        SnackBar(
          content: Text('Ошибка: ${e.toString()}'),
          backgroundColor: Colors.red,
        ),
      );
    } finally {

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

  void _showQrSourceSelection() {
    showModalBottomSheet(
      context: context,
      builder: (context) => SafeArea(
        child: Wrap(
          children: <Widget>[
            ListTile(
              leading: const Icon(Icons.camera_alt_outlined),
              title: const Text('Камера'),
              onTap: () {
                Navigator.of(context).pop();
                _scanWithCamera();
              },
            ),
            ListTile(
              leading: const Icon(Icons.photo_library_outlined),
              title: const Text('Галерея'),
              onTap: () {
                Navigator.of(context).pop();
                _scanFromGallery();
              },
            ),
          ],
        ),
      ),
    );
  }

  Future<void> _scanWithCamera() async {
    final result = await Navigator.of(context).push<String>(
      MaterialPageRoute(builder: (context) => const QrScannerScreen()),
    );
    if (result != null) await _processQrData(result);
  }

  Future<void> _scanFromGallery() async {
    final image = await ImagePicker().pickImage(source: ImageSource.gallery);
    if (image == null) return;
    final controller = MobileScannerController();
    final result = await controller.analyzeImage(image.path);
    await controller.dispose();
    if (result != null &&
        result.barcodes.isNotEmpty &&
        result.barcodes.first.rawValue != null) {
      await _processQrData(result.barcodes.first.rawValue!);
    } else {
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(
          content: Text('QR-код на изображении не найден.'),
          backgroundColor: Colors.orange,
        ),
      );
    }
  }

  Future<String?> _showPasswordDialog() {

    final passwordController = TextEditingController();
    bool isPasswordVisible = false;
    return showDialog<String>(
      context: context,
      barrierDismissible: false,
      builder: (context) => StatefulBuilder(
        builder: (context, setStateDialog) => AlertDialog(
          title: const Text('Введите пароль'),
          content: TextField(
            controller: passwordController,
            obscureText: !isPasswordVisible,
            autofocus: true,
            decoration: InputDecoration(
              labelText: 'Пароль от файла сессии',
              prefixIcon: const Icon(Icons.lock_outline),
              suffixIcon: IconButton(
                icon: Icon(
                  isPasswordVisible ? Icons.visibility_off : Icons.visibility,
                ),
                onPressed: () => setStateDialog(
                  () => isPasswordVisible = !isPasswordVisible,
                ),
              ),
            ),
          ),
          actions: [
            TextButton(
              onPressed: () => Navigator.of(context).pop(null),
              child: const Text('Отмена'),
            ),
            FilledButton(
              onPressed: () =>
                  Navigator.of(context).pop(passwordController.text),
              child: const Text('OK'),
            ),
          ],
        ),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Другие способы входа')),
      body: Stack(
        children: [
          ListView(
            padding: const EdgeInsets.all(16),
            children: [

              _AuthCard(
                icon: Icons.qr_code_scanner_rounded,
                title: 'Вход по QR-коду',
                subtitle:
                    'Отсканируйте QR-код с другого устройства, чтобы быстро войти.',
                buttonLabel: 'Сканировать QR-код',
                onPressed: _showQrSourceSelection,
              ),

              const SizedBox(height: 20),


              _AuthCard(
                icon: Icons.file_open_outlined,
                title: 'Вход по файлу сессии',
                subtitle:
                    'Загрузите ранее экспортированный .json или .ksession файл для восстановления сессии.',
                buttonLabel: 'Загрузить файл',
                onPressed: _loadSessionFile,
                isOutlined: true,
              ),

              const SizedBox(height: 20),


              _AuthCard(
                icon: Icons.vpn_key_outlined,
                title: 'Вход по токену',
                subtitle: 'Введите токен авторизации (AUTH_TOKEN) вручную.',
                buttonLabel: 'Войти с токеном',
                onPressed: _loginWithToken,
                isOutlined: true,
                child: Padding(
                  padding: const EdgeInsets.only(bottom: 16.0),
                  child: TextField(
                    controller: _tokenController,
                    decoration: const InputDecoration(
                      labelText: 'Токен',
                      border: OutlineInputBorder(),
                    ),
                  ),
                ),
              ),
            ],
          ),
          if (_isLoading)
            Container(
              color: Colors.black.withOpacity(0.5),
              child: const Center(child: CircularProgressIndicator()),
            ),
        ],
      ),
    );
  }
}


class _AuthCard extends StatelessWidget {
  final IconData icon;
  final String title;
  final String subtitle;
  final String buttonLabel;
  final VoidCallback onPressed;
  final bool isOutlined;
  final Widget? child;

  const _AuthCard({
    required this.icon,
    required this.title,
    required this.subtitle,
    required this.buttonLabel,
    required this.onPressed,
    this.isOutlined = false,
    this.child,
  });

  @override
  Widget build(BuildContext context) {
    final textTheme = Theme.of(context).textTheme;

    return Card(
      elevation: isOutlined ? 0 : 2,
      shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.circular(12),
        side: isOutlined
            ? BorderSide(
                color: Theme.of(context).colorScheme.outline.withOpacity(0.5),
              )
            : BorderSide.none,
      ),
      child: Padding(
        padding: const EdgeInsets.all(20.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            Row(
              children: [
                Icon(
                  icon,
                  size: 28,
                  color: Theme.of(context).colorScheme.primary,
                ),
                const SizedBox(width: 12),
                Text(
                  title,
                  style: textTheme.titleLarge?.copyWith(
                    fontWeight: FontWeight.bold,
                  ),
                ),
              ],
            ),
            const SizedBox(height: 8),
            Text(
              subtitle,
              style: textTheme.bodyMedium?.copyWith(
                color: Theme.of(context).colorScheme.onSurfaceVariant,
              ),
            ),
            if (child != null) ...[const SizedBox(height: 20), child!],
            const SizedBox(height: 20),
            isOutlined
                ? OutlinedButton(onPressed: onPressed, child: Text(buttonLabel))
                : FilledButton(onPressed: onPressed, child: Text(buttonLabel)),
          ],
        ),
      ),
    );
  }
}
