اريد تبديل التخزين بدلاً من sqlite اريد ان يكون في ملف json وتكون البينات مشفرة
للعلم الكود
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'dart:isolate';
import 'dart:math';
import 'dart:typed_data';
import 'package:encrypt/encrypt.dart' as encrypt;
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:http/http.dart' as http;
import 'package:micro_panel/HomePage.dart';
import 'package:micro_panel/SQLITE_HELPER/secure_storage_db.dart';
import 'package:micro_panel/main.dart';
import 'package:path_provider/path_provider.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:router_os_client/router_os_client.dart';
import 'package:smooth_page_indicator/smooth_page_indicator.dart';
import 'package:sqflite/sqflite.dart';
import 'package:flutter/foundation.dart' show kIsWeb;
import 'package:sqflite_common_ffi/sqflite_ffi.dart';

void main() async {
  // تهيئة binding قبل أي شيء آخر
  WidgetsFlutterBinding.ensureInitialized();

  if (!kIsWeb) {
    if (Platform.isAndroid || Platform.isIOS) {
      // استخدام sqflite العادي للجوال
      databaseFactory = databaseFactory;
    } else {
      // استخدام sqflite_common_ffi لسطح المكتب
      sqfliteFfiInit();
      databaseFactory = databaseFactoryFfi;
    }
  }
  // الحصول على المسار هنا
  final maindirectory = await getApplicationDocumentsDirectory();
  final saveDirectory = Directory('${maindirectory.path}/MicropanelSecrt');
  if (!await saveDirectory.exists()) {
    await saveDirectory.create(recursive: true);
  }

  final appDocumentsPath = saveDirectory.path;
  runApp(MicroPanelApp(documentsPath: appDocumentsPath));
}

class MicroPanelApp extends StatelessWidget {
  final String documentsPath;
  const MicroPanelApp({super.key, required this.documentsPath});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Micro Panel',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        fontFamily: 'Tajawal',
        useMaterial3: true,
      ),
      home: const SplashScreen(),
    );
  }
}

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

  @override
  State<SplashScreen> createState() => _SplashScreenState();
}

class _SplashScreenState extends State<SplashScreen>
    with SingleTickerProviderStateMixin {
  late final AnimationController _controller;
  late final Animation<double> _scaleAnimation;
  late final Animation<double> _fadeAnimation;
  late final Animation<Offset> _slideAnimation;

  @override
  void initState() {
    super.initState();
    _initAnimations();
    _navigateToLogin();
  }

  void _initAnimations() {
    _controller = AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 800),
    );
    _scaleAnimation = Tween<double>(begin: 0.9, end: 1.0).animate(
      CurvedAnimation(parent: _controller, curve: Curves.easeInOutQuart),
    );
    _fadeAnimation = Tween<double>(
      begin: 0.0,
      end: 1.0,
    ).animate(CurvedAnimation(parent: _controller, curve: Curves.easeIn));
    _slideAnimation = Tween<Offset>(
      begin: const Offset(0.0, 0.3),
      end: Offset.zero,
    ).animate(CurvedAnimation(parent: _controller, curve: Curves.easeOutQuart));
    _controller.forward();
  }

  void _navigateToLogin() {
    Future.delayed(const Duration(seconds: 1), () {
      if (mounted) {
        Navigator.pushReplacement(
          context,
          PageRouteBuilder(
            pageBuilder: (_, __, ___) => const Login(),
            transitionsBuilder:
                (_, animation, __, child) =>
                    FadeTransition(opacity: animation, child: child),
            transitionDuration: const Duration(milliseconds: 500),
          ),
        );
      }
    });
  }

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: const Color(0xFF0A192F),
      body: Stack(
        children: [_buildBackgroundCircles(), Center(child: _buildContent())],
      ),
    );
  }

  Widget _buildBackgroundCircles() {
    return Stack(
      children: [
        Positioned(
          top: -50,
          right: -50,
          child: Container(
            width: 200,
            height: 200,
            decoration: BoxDecoration(
              shape: BoxShape.circle,
              color: Color(0xFF1E3A8A).withOpacity(0.2),
            ),
          ),
        ),
        Positioned(
          bottom: -100,
          left: -100,
          child: Container(
            width: 300,
            height: 300,
            decoration: BoxDecoration(
              shape: BoxShape.circle,
              color: Color(0xFF1E3A8A).withOpacity(0.1),
            ),
          ),
        ),
      ],
    );
  }

  Widget _buildContent() {
    return Padding(
      padding: const EdgeInsets.all(20.0),
      child: Directionality(
        textDirection: TextDirection.rtl,
        child: ScaleTransition(
          scale: _scaleAnimation,
          child: FadeTransition(
            opacity: _fadeAnimation,
            child: SlideTransition(
              position: _slideAnimation,
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  _buildAppLogo(),
                  const SizedBox(height: 20),
                  _buildAppTitle(),
                  const SizedBox(height: 5),
                  _buildAppSubtitle(),
                  const SizedBox(height: 30),
                  _buildLoadingIndicator(),
                  const SizedBox(height: 15),
                  _buildLoadingText(),
                ],
              ),
            ),
          ),
        ),
      ),
    );
  }

  Widget _buildAppLogo() {
    return Hero(
      tag: 'app-logo',
      child: Container(
        height: 150,
        width: 150, // تأكد من أن العرض مساوٍ للارتفاع للحفاظ على الشكل الدائري
        padding: const EdgeInsets.all(5),
        decoration: BoxDecoration(
          color: Colors.white.withOpacity(0.1),
          shape: BoxShape.circle,
          border: Border.all(color: Colors.white.withOpacity(0.2), width: 1.5),
        ),
        child: ClipOval(
          child: Image.asset(
            'assets/img/MicroPanel.ico',
            fit: BoxFit.cover, // يجعل الصورة تملأ الحاوية بشكل متناسق
          ),
        ),
      ),
    );
  }

  Widget _buildAppTitle() {
    return const Text(
      'Micro Panel',
      style: TextStyle(
        fontFamily: 'Tajawal',
        fontSize: 30,
        fontWeight: FontWeight.bold,
        color: Colors.white,
        letterSpacing: 1.2,
      ),
    );
  }

  Widget _buildAppSubtitle() {
    return const Text(
      'نظام إدارة أجهزة الميكروتك',
      style: TextStyle(
        fontFamily: 'Tajawal',
        color: Colors.white70,
        fontSize: 14,
      ),
    );
  }

  Widget _buildLoadingIndicator() {
    return SizedBox(
      width: 180,
      child: ClipRRect(
        borderRadius: BorderRadius.circular(8),
        child: LinearProgressIndicator(
          valueColor: AlwaysStoppedAnimation<Color>(
            Colors.white.withOpacity(0.9),
          ),
          backgroundColor: Colors.white.withOpacity(0.2),
          minHeight: 5,
        ),
      ),
    );
  }

  Widget _buildLoadingText() {
    return const Text(
      'جاري التحميل...',
      style: TextStyle(
        fontFamily: 'Tajawal',
        color: Colors.white,
        fontSize: 14,
      ),
    );
  }
}

class MikroTikApi {
  Socket? _socket;
  final String host;
  final int port;
  final String user, pass;
  final _recvBuffer = <int>[];

  MikroTikApi({
    required this.host,
    this.port = 8728,
    required this.user,
    required this.pass,
  });

  Future<void> connect() async {
    _socket = await Socket.connect(host, port);
    _socket!.listen(_onData, onError: _onError, onDone: _onDone);
  }

  void _onData(Uint8List chunk) {
    _recvBuffer.addAll(chunk);
  }

  void _onError(e) => throw 'خطأ في الاتصال';
  void _onDone() => _socket = null;

  Uint8List _encodeWord(String s) {
    final b = utf8.encode(s);
    final len = b.length;
    final header = <int>[];
    if (len < 0x80)
      header.add(len);
    else if (len < 0x4000) {
      header.add((len >> 8) | 0x80);
      header.add(len & 0xFF);
    } else if (len < 0x200000) {
      header.add((len >> 16) | 0xC0);
      header.add((len >> 8) & 0xFF);
      header.add(len & 0xFF);
    } else {
      header.add((len >> 24) | 0xE0);
      header.add((len >> 16) & 0xFF);
      header.add((len >> 8) & 0xFF);
      header.add(len & 0xFF);
    }
    return Uint8List.fromList([...header, ...b]);
  }

  Future<Map<String, String>?> fetchLicenseData() async {
    await sendSentence(['/system/license/print']);
    final resp = await _readSentences();

    Map<String, String> licenseData = {};

    for (var sentence in resp) {
      if (sentence.isNotEmpty && sentence.first == '!re') {
        for (var token in sentence.skip(1)) {
          if (token.startsWith('=')) {
            final parts = token.substring(1).split('=');
            if (parts.length >= 2) {
              final key = parts[0];
              final value = parts.sublist(1).join('=');
              licenseData[key] = value;
            }
          }
        }
        break;
      }
    }

    if (licenseData.isEmpty) return null;
    return licenseData;
  }

  Future<bool> isLicenseDataStored() async {
    final storage = SecureStorageDB();

    final softwareId = await storage.read('license_software_id');
    // افعل نفس الشيء لمفاتيح أخرى إذا تريد

    return softwareId != null;
  }

  String encryptAES(String plainText, String keyString, String ivString) {
    final key = encrypt.Key.fromUtf8(keyString);
    final iv = encrypt.IV.fromUtf8(ivString);
    final encrypter = encrypt.Encrypter(
      encrypt.AES(key, mode: encrypt.AESMode.cbc),
    );

    final encrypted = encrypter.encrypt(plainText, iv: iv);
    return encrypted.base64;
  }

  Future<String> fetchRouterVersion(String appDocumentsPath) async {
    await sendSentence(['/system/resource/print']);
    final resp = await _readSentences();

    for (var sentence in resp) {
      if (sentence.isNotEmpty && sentence.first == '!re') {
        for (var token in sentence.skip(1)) {
          if (token.startsWith('=version=')) {
            final fullVersion = token.substring('=version='.length);
            final majorVersion = fullVersion.split('.').first;

            final data = {'router_version': majorVersion};
            final jsonString = jsonEncode(data);

            final filePath = '$appDocumentsPath/router_version.json';
            final file = File(filePath);

            await file.writeAsString(jsonString);
            print('تم حفظ إصدار الراوتر بنجاح في: $filePath');

            return majorVersion;
          }
        }
      }
    }

    throw Exception('لم يتم العثور على إصدار الراوتر في الاستجابة');
  }

  Future<List<Map<String, dynamic>>> fetchUserManagerUsers(
    String appDocumentsPath,
  ) async {
    // جلب إصدار الراوتر أولاً
    final versionString = await fetchRouterVersion(appDocumentsPath);
    final version = versionString.startsWith('7') ? 7 : 6;
    print('$version');

    // جلب بيانات المستخدمين الأساسية
    if (version == 7) {
      await sendSentence(['/user-manager/user/print']);
    } else {
      await sendSentence(['/tool/user-manager/user/print']);
    }

    final usersResp = await _readSentences();
    final users = <Map<String, dynamic>>[];

    // معالجة بيانات المستخدمين الأساسية
    for (var sentence in usersResp) {
      if (sentence.isNotEmpty && sentence.first == '!re') {
        final user = <String, dynamic>{};
        for (var token in sentence.skip(1)) {
          if (token.startsWith('=')) {
            final parts = token.split('=');
            if (parts.length >= 3) {
              user[parts[1]] = parts.sublist(2).join('=');
            }
          }
        }
        if (user.isNotEmpty) {
          final filteredUser =
              version == 7
                  ? {
                    '.id': user['.id'],
                    'name': user['name'],
                    'password': user['password'],
                    'otp-secret': user['otp-secret'],
                    'group': user['group'],
                    'shared-users': user['shared-users'],
                    'attributes': user['attributes'],
                    'disabled': user['disabled'],
                  }
                  : {
                    '.id': user['.id'],
                    'actual-profile': user['actual-profile'] ?? '',
                    'username': user['name'] ?? user['username'] ?? '',
                    'password': user['password'] ?? '',
                    'uptime-used': user['uptime-used'] ?? '',
                    'download-used': user['download-used'] ?? '',
                    'upload-used': user['upload-used'] ?? '',
                    'last-seen': user['last-seen'] ?? '',
                    'disabled':
                        user['disabled'] ??
                        (user['flags']?.contains('X') ?? false),
                    'active': user['flags']?.contains('A') ?? false,
                    'incomplete': user['flags']?.contains('I') ?? false,
                  };
          users.add(filteredUser);
        }
      }
    }

    if (version == 7) {
      await sendSentence(['/user-manager/user-profile/print']);
      final profilesResp = await _readSentences();
      final profiles = <Map<String, String>>[];

      for (var sentence in profilesResp) {
        if (sentence.isNotEmpty && sentence.first == '!re') {
          final profile = <String, String>{};
          for (var token in sentence.skip(1)) {
            if (token.startsWith('=')) {
              final parts = token.split('=');
              if (parts.length >= 3) {
                profile[parts[1]] = parts.sublist(2).join('=');
              }
            }
          }
          if (profile.isNotEmpty) {
            profiles.add(profile);
          }
        }
      }

      for (var user in users) {
        final userName = user['name'];
        if (userName != null) {
          final matchingProfile = profiles.firstWhere(
            (profile) => profile['user'] == userName,
            orElse: () => {},
          );

          if (matchingProfile.isNotEmpty) {
            user.addAll({
              'profile': matchingProfile['profile'] ?? '',
              'state': matchingProfile['state'] ?? '',
              'end-time': matchingProfile['end-time'] ?? '',
            });
          }
        }
      }
    }

    final file = File('$appDocumentsPath/user_manager_users.json');
    await file.writeAsString(jsonEncode(users));

    return users;
  }

  Future<void> sendSentence(List<String> words) async {
    final out = <int>[];
    for (var w in words) out.addAll(_encodeWord(w));
    out.add(0);
    _socket!.add(out);
    await _socket!.flush();
  }

  Future<List<List<String>>> _readSentences() async {
    final sentences = <List<String>>[];
    while (true) {
      await Future.delayed(Duration(milliseconds: 100));

      if (_recvBuffer.isEmpty) continue;

      final buf = List<int>.from(_recvBuffer);
      try {
        var i = 0;
        while (i < buf.length) {
          final sentence = <String>[];
          while (i < buf.length && buf[i] != 0) {
            int len = buf[i++];
            int bytesCount = 1;

            if (len & 0x80 != 0) {
              bytesCount =
                  (len & 0xC0) == 0x80
                      ? 2
                      : (len & 0xE0) == 0xC0
                      ? 3
                      : 4;
              len = ((len & 0x7F) << ((bytesCount - 1) * 8));

              for (int j = 0; j < bytesCount - 1 && i < buf.length; j++) {
                len |= buf[i++] << ((bytesCount - 2 - j) * 8);
              }
            }

            if (i + len > buf.length) {
              i -= bytesCount;
              break;
            }

            sentence.add(utf8.decode(buf.sublist(i, i + len)));
            i += len;
          }

          if (i < buf.length && buf[i] == 0) {
            i++; // تخطي حرف الإنهاء
            sentences.add(sentence);

            // إذا كانت الجملة تحتوي على !done، نخرج
            if (sentence.isNotEmpty && sentence.first == '!done') {
              _recvBuffer.removeRange(0, i);
              return sentences;
            }
          } else {
            break; // بيانات غير مكتملة
          }
        }

        _recvBuffer.removeRange(0, i);

        // إذا وجدنا جملة !done نعود بالنتيجة
        if (sentences.any((s) => s.isNotEmpty && s.first == '!done')) {
          return sentences;
        }
      } catch (e) {
        print('Error parsing sentences');
        break;
      }
    }
    return sentences;
  }

  Future<bool> login() async {
    await sendSentence(['/login', '=name=$user', '=password=$pass']);
    final resp = await _readSentences();
    return resp.any((s) => s.first == '!done');
  }

  Future<List<Map<String, String>>> fetchHotspotUsers() async {
    await sendSentence(['/ip/hotspot/user/print']);
    final resp = await _readSentences();
    return resp.where((s) => s.first == '!re').map((s) {
      final m = <String, String>{};
      for (var tok in s.skip(1)) {
        if (tok.startsWith('=')) {
          final idx = tok.indexOf('=', 1);
          if (idx != -1) {
            final key = tok.substring(1, idx);
            final value = tok.substring(idx + 1);
            m[key] = value;
          }
        }
      }

      return m;
    }).toList();
  }

  void close() => _socket?.destroy();
}

enum UserType { hotspot, userManager }

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

  @override
  State<Login> createState() => _LoginState();
}

class _LoginState extends State<Login> {
  final _formKey = GlobalKey<FormState>();
  final TextEditingController _ipController = TextEditingController();
  final FocusNode _ipFocusNode = FocusNode();
  final _usernameController = TextEditingController();
  final _passwordController = TextEditingController();
  final _portController = TextEditingController(text: '8728');
  bool _isLoading = false;
  bool _obscurePassword = true;
  bool _autoFetchEnabled = false;
  bool _hasSavedCredentials = false;
  bool _isActivated = false;

  Map<String, dynamic>? _savedCredentials;
  UserType _selectedUserType = UserType.hotspot;

  final PageController _pageController = PageController();
  int _currentPage = 0;

  bool _showText = false;

  final List<Map<String, dynamic>> _slides = [
    {
      'image': 'assets/img/1.png',
      'title': 'إدارة متكاملة',
      'description': 'تحكم كامل في جميع اصدارات الميكروتك من نظام واحد',
    },
    {
      'image': 'assets/img/2.png',
      'title': 'تقارير مفصلة',
      'description': 'احصل على تقارير أداء دقيقة لشبكتك',
    },
  ];

  final String firebaseUrl =
      'https://micropanel-b67e0-default-rtdb.firebaseio.com/information.json';

  // المفتاح (32 بايت = 256 بت)
  final String aesKey =
      'my32lengthsupersecretnooneknows1'; // يجب أن يكون 32 حرفًا
  final String aesIV = '8bytesiv12345678'; // يجب أن يكون 16 حرفًا

  String? phone;
  String? Urlapi;

  String decryptAES(String encryptedText, String keyString, String ivString) {
    try {
      final key = encrypt.Key.fromUtf8(keyString);
      final iv = encrypt.IV.fromUtf8(ivString);
      final encrypter = encrypt.Encrypter(
        encrypt.AES(key, mode: encrypt.AESMode.cbc),
      );

      // تنظيف النص المشفر من الأحرف غير الصالحة
      final cleanedEncryptedText = encryptedText
          .replaceAll('\n', '')
          .replaceAll('\r', '')
          .replaceAll(' ', '');

      final encrypted = encrypt.Encrypted.fromBase64(cleanedEncryptedText);
      final decrypted = encrypter.decrypt(encrypted, iv: iv);
      return decrypted;
    } catch (e) {
      print('Error decrypting AES: $e');
      rethrow;
    }
  }

  Future<void> fetchJsonFromFirebase() async {
    try {
      final response = await http.get(Uri.parse(firebaseUrl));

      if (response.statusCode == 200) {
        final Map<String, dynamic> data =
            jsonDecode(response.body) as Map<String, dynamic>;

        // التحقق من وجود البيانات قبل فك التشفير
        if (data['phone'] != null && data['Urlapi'] != null) {
          phone = decryptAES(data['phone'].toString(), aesKey, aesIV);
          Urlapi = decryptAES(data['Urlapi'].toString(), aesKey, aesIV);
          print('phone: $phone');
          print('Urlapi:$Urlapi');
        } else {
          throw Exception('بيانات التشفير غير موجودة في الاستجابة');
        }
      } else {
        throw http.ClientException(
          'حدث خطأ أثناء جلب البيانات: ${response.statusCode}',
        );
      }
    } catch (e, st) {
      print('Error fetching or decrypting config from Firebase: $e\n$st');
      throw Exception('فشل في جلب أو فك تشفير الإعدادات: $e');
    }
  }

  @override
  void initState() {
    super.initState();
    _requestFilePickerPermissions();
    _loadSavedCredentials();
    _startAutoSlide();
    Future.delayed(Duration(milliseconds: 150), () {
      fetchJsonFromFirebase();
    });
    checkActivation().then((isActivated) {
      if (mounted) {
        setState(() {
          _isActivated = isActivated;
        });
      }
    });

    @override
    void didPopNext() {
      checkActivation().then((isActivated) {
        if (mounted) {
          setState(() {
            _isActivated = isActivated;
          });
        }
      });
    }

    Future.delayed(Duration(seconds: 1), () {
      if (!mounted) return;
      setState(() => _showText = true);

      Future.delayed(Duration(seconds: 4), () {
        if (!mounted) return;
        setState(() => _showText = false);
      });
    });
  }

  Future<void> _requestFilePickerPermissions() async {
    if (Platform.isAndroid) {
      if (Platform.version.contains("13") || Platform.version.contains("14")) {
        // لا تحتاج لإذن خاص على Android 13+ عند استخدام FilePicker
        return;
      }

      final permissions = [
        Permission.storage,
        if (Platform.isAndroid && Platform.version.contains("11"))
          Permission.manageExternalStorage,
      ];

      final statuses = await permissions.request();

      if (statuses[Permission.storage]?.isDenied ?? false) {
        // التخزين مرفوض
        print('تم رفض إذن التخزين');
      }

      if (statuses[Permission.manageExternalStorage]?.isDenied ?? false) {
        // إدارة التخزين مرفوضة
        print('تم رفض إذن إدارة التخزين');
      }

      if (statuses[Permission.manageExternalStorage]?.isPermanentlyDenied ??
          false) {
        // يجب توجيه المستخدم للإعدادات
        await openAppSettings();
      }
    }
  }

  Future<void> _loadSavedCredentials() async {
    try {
      final maindirectory = await getApplicationDocumentsDirectory();
      final saveDirectory = Directory('${maindirectory.path}/MicropanelSecrt');
      if (!await saveDirectory.exists()) {
        await saveDirectory.create(recursive: true);
      }
      final file = File('${saveDirectory.path}/login_credentials.json');
      if (await file.exists()) {
        final encryptedContent = await file.readAsString();

        if (encryptedContent.isEmpty) return;

        final key = encrypt.Key.fromUtf8(aesKey);
        final iv = encrypt.IV.fromUtf8(aesIV);

        final encrypter = encrypt.Encrypter(
          encrypt.AES(key, mode: encrypt.AESMode.cbc),
        );

        final decrypted = encrypter.decrypt64(encryptedContent, iv: iv);

        final credentials = jsonDecode(decrypted);

        if (credentials != null && credentials is Map) {
          setState(() {
            _savedCredentials = Map<String, dynamic>.from(credentials);
            _hasSavedCredentials = true;
            _ipController.text = _savedCredentials?['ip'] ?? '';
            _usernameController.text = _savedCredentials?['username'] ?? '';
            _passwordController.text = _savedCredentials?['password'] ?? '';
            _portController.text = _savedCredentials?['port'] ?? '8728';

            int selectedTabIndex = _savedCredentials?['selectedTab'] ?? 0;
            _selectedUserType =
                selectedTabIndex == 0 ? UserType.hotspot : UserType.userManager;
          });
        }
      }
    } catch (e) {
      print('Error loading encrypted credentials: $e');
    }
  }

  Future<void> _saveCredentials() async {
    try {
      final maindirectory = await getApplicationDocumentsDirectory();
      final saveDirectory = Directory('${maindirectory.path}/MicropanelSecrt');
      if (!await saveDirectory.exists()) {
        await saveDirectory.create(recursive: true);
      }
      final file = File('${saveDirectory.path}/login_credentials.json');

      final credentials = {
        'ip': _ipController.text,
        'username': _usernameController.text,
        'password': _passwordController.text,
        'port': _portController.text,
        'selectedTab': _selectedUserType == UserType.hotspot ? 0 : 1,
      };

      // تحويل إلى JSON String
      final plainText = jsonEncode(credentials);

      // مفاتيح مسبقة (يفضل توليدها بشكل ثابت وآمن)
      final key = encrypt.Key.fromUtf8(aesKey); // يجب أن تكون 32 بايت
      final iv = encrypt.IV.fromUtf8(aesIV); // 16 بايت

      final encrypter = encrypt.Encrypter(
        encrypt.AES(key, mode: encrypt.AESMode.cbc),
      );

      final encrypted = encrypter.encrypt(plainText, iv: iv);

      await file.writeAsString(encrypted.base64);

      setState(() {
        _hasSavedCredentials = true;
        _savedCredentials = credentials;
      });
    } catch (e) {
      print('Error saving encrypted credentials: $e');
    }
  }

  @override
  void dispose() {
    _ipController.dispose();
    _ipFocusNode.dispose();
    _usernameController.dispose();
    _passwordController.dispose();
    _portController.dispose();
    _pageController.dispose();
    super.dispose();
  }

  void _startAutoSlide() {
    Future.delayed(Duration(seconds: 5), () {
      if (_pageController.hasClients) {
        final nextPage =
            _currentPage < _slides.length - 1 ? _currentPage + 1 : 0;
        _pageController.animateToPage(
          nextPage,
          duration: Duration(milliseconds: 800),
          curve: Curves.easeInOutCubic,
        );
        _startAutoSlide();
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    final size = MediaQuery.of(context).size;
    final isMobile = size.width < 600;
    return Directionality(
      textDirection: TextDirection.rtl,
      child: Scaffold(
        backgroundColor: const Color(0xFF0A192F),
        body: SafeArea(
          child: LayoutBuilder(
            builder: (context, constraints) {
              if (constraints.maxWidth > 800) {
                return Row(
                  children: [
                    Expanded(
                      flex: 5,
                      child: Stack(
                        children: [
                          Container(
                            padding: const EdgeInsets.symmetric(horizontal: 40),
                            color: const Color(0xFF0A192F),
                            child: Center(child: _buildLoginForm(isMobile)),
                          ),
                          Positioned(
                            top: 10,
                            right: 10,
                            child: InkWell(
                              onTap:
                                  _isActivated
                                      ? null
                                      : () => showSerialNumberDialog(context),
                              child: AnimatedContainer(
                                height: 40,
                                duration: Duration(milliseconds: 800),
                                curve: Curves.easeInOutQuad,
                                decoration: BoxDecoration(
                                  color:
                                      _isActivated
                                          ? Colors.blue.withOpacity(0.95)
                                          : Colors.amberAccent[400]!
                                              .withOpacity(0.95),
                                  borderRadius: BorderRadius.circular(25.0),
                                ),
                                padding: EdgeInsets.symmetric(horizontal: 10),
                                alignment: Alignment.center,
                                child: AnimatedSize(
                                  duration: Duration(milliseconds: 1000),
                                  curve: Curves.easeInOutBack,
                                  child: Row(
                                    mainAxisSize: MainAxisSize.min,
                                    children: [
                                      Icon(
                                        _isActivated
                                            ? Icons.verified
                                            : Icons.touch_app_outlined,
                                        color: Colors.white,
                                        size: 20,
                                      ),
                                      AnimatedSwitcher(
                                        duration: Duration(milliseconds: 800),
                                        switchInCurve: Curves.easeOutCubic,
                                        switchOutCurve: Curves.easeInCubic,
                                        transitionBuilder:
                                            (child, animation) =>
                                                ScaleTransition(
                                                  scale: animation,
                                                  child: FadeTransition(
                                                    opacity: animation,
                                                    child: child,
                                                  ),
                                                ),
                                        child:
                                            _showText || _isActivated
                                                ? Padding(
                                                  padding: EdgeInsets.only(
                                                    left: 8,
                                                  ),
                                                  key: ValueKey(
                                                    _isActivated
                                                        ? 'activated'
                                                        : 'text',
                                                  ),
                                                  child: Text(
                                                    _isActivated
                                                        ? '  تم التفعيل'
                                                        : '  طلب التفعيل',
                                                    style: TextStyle(
                                                      color: Colors.white,
                                                      fontFamily: 'Tajawal',
                                                      fontSize: 13,
                                                      fontWeight:
                                                          FontWeight.bold,
                                                      shadows: [
                                                        Shadow(
                                                          color: Colors.black
                                                              .withOpacity(0.2),
                                                          blurRadius: 2,
                                                          offset: Offset(1, 1),
                                                        ),
                                                      ],
                                                    ),
                                                  ),
                                                )
                                                : SizedBox.shrink(
                                                  key: ValueKey('empty'),
                                                ),
                                      ),
                                    ],
                                  ),
                                ),
                              ),
                            ),
                          ),
                        ],
                      ),
                    ),
                    Expanded(
                      flex: 6,
                      child: Container(
                        decoration: const BoxDecoration(
                          color: Color(0xFF0A192F),
                        ),
                        child: Stack(
                          children: [
                            // Image Slider
                            PageView.builder(
                              controller: _pageController,
                              itemCount: _slides.length,
                              onPageChanged: (index) {
                                setState(() {
                                  _currentPage = index;
                                });
                              },
                              itemBuilder: (context, index) {
                                return Container(
                                  decoration: BoxDecoration(
                                    image: DecorationImage(
                                      image: AssetImage(
                                        _slides[index]['image'],
                                      ),
                                      fit: BoxFit.contain,
                                    ),
                                  ),
                                  child: Container(
                                    decoration: BoxDecoration(
                                      gradient: LinearGradient(
                                        begin: Alignment.topCenter,
                                        end: Alignment.bottomCenter,
                                        colors: [
                                          Colors.transparent,
                                          Colors.black.withOpacity(0.7),
                                        ],
                                      ),
                                    ),
                                  ),
                                );
                              },
                            ),

                            // Content Overlay
                            Positioned(
                              bottom: 80,
                              left: 0,
                              right: 0,
                              child: AnimatedSwitcher(
                                duration: Duration(milliseconds: 500),
                                child: Container(
                                  key: ValueKey<int>(_currentPage),
                                  padding: EdgeInsets.symmetric(horizontal: 40),
                                  child: Column(
                                    children: [
                                      Text(
                                        _slides[_currentPage]['title'],
                                        style: TextStyle(
                                          fontFamily: 'Tajawal',
                                          color: Colors.white,
                                          fontSize: 28,
                                          fontWeight: FontWeight.bold,
                                        ),
                                      ),
                                      SizedBox(height: 15),
                                      Text(
                                        _slides[_currentPage]['description'],
                                        textAlign: TextAlign.center,
                                        style: TextStyle(
                                          fontFamily: 'Tajawal',
                                          color: Colors.white70,
                                          fontSize: 18,
                                        ),
                                      ),
                                    ],
                                  ),
                                ),
                              ),
                            ),

                            Positioned(
                              bottom: 40,
                              left: 0,
                              right: 0,
                              child: Center(
                                child: SmoothPageIndicator(
                                  controller: _pageController,
                                  count: _slides.length,
                                  effect: const ExpandingDotsEffect(
                                    dotHeight: 8,
                                    dotWidth: 8,
                                    activeDotColor: Color(0xFF64FFDA),
                                    dotColor: Colors.white54,
                                    spacing: 10,
                                  ),
                                ),
                              ),
                            ),
                          ],
                        ),
                      ),
                    ),
                  ],
                );
              } else {
                return CustomScrollView(
                  slivers: [
                    SliverFillRemaining(
                      hasScrollBody: false,
                      child: Stack(
                        children: [
                          Container(
                            padding: const EdgeInsets.symmetric(
                              horizontal: 20,
                              vertical: 40,
                            ),
                            child: _buildLoginForm(isMobile),
                          ),
                          Positioned(
                            top: 10,
                            right: 10,
                            child: InkWell(
                              onTap: () => showSerialNumberDialog(context),
                              child: AnimatedContainer(
                                height: 40,
                                duration: Duration(milliseconds: 800),
                                curve: Curves.easeInOutQuad,
                                decoration: BoxDecoration(
                                  color: Colors.amberAccent[400]!.withOpacity(
                                    0.95,
                                  ),
                                  borderRadius: BorderRadius.circular(25.0),
                                ),
                                padding: EdgeInsets.symmetric(horizontal: 10),
                                alignment: Alignment.center,
                                child: AnimatedSize(
                                  duration: Duration(milliseconds: 1000),
                                  curve: Curves.easeInOutBack,
                                  child: Row(
                                    mainAxisSize: MainAxisSize.min,
                                    children: [
                                      Icon(
                                        Icons.touch_app_outlined,
                                        color: Colors.white,
                                        size: 20,
                                      ),
                                      AnimatedSwitcher(
                                        duration: Duration(milliseconds: 800),
                                        switchInCurve: Curves.easeOutCubic,
                                        switchOutCurve: Curves.easeInCubic,
                                        transitionBuilder:
                                            (child, animation) =>
                                                ScaleTransition(
                                                  scale: animation,
                                                  child: FadeTransition(
                                                    opacity: animation,
                                                    child: child,
                                                  ),
                                                ),
                                        child:
                                            _showText
                                                ? Padding(
                                                  padding: EdgeInsets.only(
                                                    left: 8,
                                                  ),
                                                  key: ValueKey('text'),
                                                  child: Text(
                                                    'طلب التفعيل',
                                                    style: TextStyle(
                                                      color: Colors.white,
                                                      fontFamily: 'Tajawal',
                                                      fontSize: 13,
                                                      fontWeight:
                                                          FontWeight.bold,
                                                      shadows: [
                                                        Shadow(
                                                          color: Colors.black
                                                              .withOpacity(0.2),
                                                          blurRadius: 2,
                                                          offset: Offset(1, 1),
                                                        ),
                                                      ],
                                                    ),
                                                  ),
                                                )
                                                : SizedBox.shrink(
                                                  key: ValueKey('empty'),
                                                ),
                                      ),
                                    ],
                                  ),
                                ),
                              ),
                            ),
                          ),
                        ],
                      ),
                    ),
                  ],
                );
              }
            },
          ),
        ),
      ),
    );
  }

  void showSerialNumberDialog(BuildContext context) {
    final TextEditingController serial1Controller = TextEditingController();
    final TextEditingController serial2Controller = TextEditingController();
    final FocusNode serial1Focus = FocusNode();
    final FocusNode serial2Focus = FocusNode();

    showDialog(
      context: context,
      barrierDismissible: false,
      builder: (BuildContext context) {
        return Directionality(
          textDirection: TextDirection.rtl,
          child: Center(
            child: ConstrainedBox(
              constraints: BoxConstraints(maxWidth: 500, minWidth: 300),
              child: Dialog(
                backgroundColor: Colors.transparent,
                elevation: 0,
                child: SingleChildScrollView(
                  child: Container(
                    decoration: BoxDecoration(
                      color: Colors.white,
                      borderRadius: BorderRadius.circular(20),
                      boxShadow: [
                        BoxShadow(
                          color: Colors.black.withOpacity(0.15),
                          blurRadius: 24,
                          spreadRadius: 2,
                        ),
                      ],
                    ),
                    child: Column(
                      mainAxisSize: MainAxisSize.min,
                      children: [
                        _buildModernHeader(context),
                        Padding(
                          padding: const EdgeInsets.symmetric(
                            horizontal: 24,
                            vertical: 16,
                          ),
                          child: Column(
                            crossAxisAlignment: CrossAxisAlignment.stretch,
                            children: [
                              const Text(
                                'إدخال أرقام السيريال',
                                style: TextStyle(
                                  fontSize: 24,
                                  fontWeight: FontWeight.bold,
                                  color: Color(0xFF1A3052),
                                ),
                                textAlign: TextAlign.center,
                              ),
                              const SizedBox(height: 8),
                              Text(
                                'الرجاء إدخال رقمي السيريال الموجودين على المنتج',
                                textAlign: TextAlign.center,
                                style: TextStyle(
                                  color: Colors.grey[600],
                                  fontSize: 15,
                                  height: 1.4,
                                ),
                              ),
                              const SizedBox(height: 24),
                              _buildSerialField(
                                controller: serial1Controller,
                                focusNode: serial1Focus,
                                nextFocusNode: serial2Focus,
                                label: 'السيريال الأول',
                                icon: Icons.confirmation_number_outlined,
                                isFirstField: true,
                              ),
                              const SizedBox(height: 16),
                              _buildSerialField(
                                controller: serial2Controller,
                                focusNode: serial2Focus,
                                label: 'السيريال الثاني',
                                icon: Icons.confirmation_number_outlined,
                                isLastField: true,
                              ),
                              const SizedBox(height: 16),
                              Row(
                                children: [
                                  Text(
                                    'للطلب عبر الوتساب :',
                                    textAlign: TextAlign.center,
                                    style: TextStyle(
                                      color: Colors.grey[600],
                                      fontSize: 14,
                                    ),
                                  ),
                                  Text(
                                    '${phone ?? '+(967)xxxxxx '}',
                                    textDirection: TextDirection.ltr,
                                    style: TextStyle(
                                      color: Colors.grey[600],
                                      fontSize: 14,
                                    ),
                                  ),
                                ],
                              ),
                              const SizedBox(height: 24),
                              _buildModernActionButtons(
                                context: context,
                                serial1Controller: serial1Controller,
                                serial2Controller: serial2Controller,
                              ),
                              const SizedBox(height: 8),
                            ],
                          ),
                        ),
                      ],
                    ),
                  ),
                ),
              ),
            ),
          ),
        );
      },
    );
  }

  Widget _buildModernHeader(BuildContext context) {
    return Container(
      height: 120,
      decoration: BoxDecoration(
        color: const Color(0xFF1A3052),
        borderRadius: const BorderRadius.only(
          topLeft: Radius.circular(20),
          topRight: Radius.circular(20),
        ),
        boxShadow: [
          BoxShadow(
            color: Colors.black.withOpacity(0.1),
            blurRadius: 10,
            spreadRadius: 2,
          ),
        ],
      ),
      child: Stack(
        children: [
          Positioned(
            top: 0,
            right: 0,
            child: Container(
              width: 100,
              height: 100,
              decoration: BoxDecoration(
                color: const Color(0xFF2A5591).withOpacity(0.2),
                borderRadius: const BorderRadius.only(
                  bottomLeft: Radius.circular(100),
                ),
              ),
            ),
          ),
          Positioned(
            bottom: 0,
            left: 0,
            child: Container(
              width: 80,
              height: 80,
              decoration: BoxDecoration(
                color: const Color(0xFF2A5591).withOpacity(0.15),
                borderRadius: const BorderRadius.only(
                  topRight: Radius.circular(80),
                ),
              ),
            ),
          ),
          Positioned(
            top: 16,
            left: 16,
            child: IconButton(
              icon: const Icon(Icons.close, color: Colors.white, size: 28),
              onPressed: () => Navigator.pop(context),
            ),
          ),
          const Center(
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: [
                Icon(Icons.verified_outlined, color: Colors.white, size: 32),
                SizedBox(height: 8),
                Text(
                  'التفعيل',
                  style: TextStyle(
                    color: Colors.white,
                    fontSize: 18,
                    fontWeight: FontWeight.bold,
                  ),
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }

  Widget _buildSerialField({
    required TextEditingController controller,
    required FocusNode focusNode,
    FocusNode? nextFocusNode,
    required String label,
    required IconData icon,
    bool isFirstField = false,
    bool isLastField = false,
  }) {
    return TextFormField(
      controller: controller,
      focusNode: focusNode,
      textInputAction:
          isLastField ? TextInputAction.done : TextInputAction.next,
      onFieldSubmitted: (_) {
        if (!isLastField && nextFocusNode != null) {
          FocusScope.of(focusNode.context!).requestFocus(nextFocusNode);
        }
      },
      textAlign: TextAlign.right,
      style: const TextStyle(color: Color(0xFF333333), fontSize: 16),
      decoration: InputDecoration(
        labelText: label,
        labelStyle: const TextStyle(color: Color(0xFF1A3052), fontSize: 15),
        prefixIcon: Container(
          margin: const EdgeInsets.only(right: 12),
          child: Icon(
            icon,
            color: const Color(0xFF1A3052).withOpacity(0.7),
            size: 22,
          ),
        ),
        filled: true,
        fillColor: Colors.grey[50],
        border: OutlineInputBorder(
          borderRadius: BorderRadius.circular(12),
          borderSide: BorderSide.none,
        ),
        enabledBorder: OutlineInputBorder(
          borderRadius: BorderRadius.circular(12),
          borderSide: BorderSide(color: Colors.grey[300]!, width: 1),
        ),
        focusedBorder: OutlineInputBorder(
          borderRadius: BorderRadius.circular(12),
          borderSide: const BorderSide(color: Color(0xFF1A3052), width: 1.5),
        ),
        contentPadding: const EdgeInsets.symmetric(
          horizontal: 16,
          vertical: 16,
        ),
        suffixIcon: IconButton(
          icon: Icon(
            Icons.paste,
            color: const Color(0xFF1A3052).withOpacity(0.6),
            size: 20,
          ),
          onPressed: () => _pasteFromClipboard(controller),
        ),
      ),
    );
  }

  Widget _buildModernActionButtons({
    required BuildContext context,
    required TextEditingController serial1Controller,
    required TextEditingController serial2Controller,
  }) {
    return Row(
      children: [
        Expanded(
          child: OutlinedButton(
            style: OutlinedButton.styleFrom(
              foregroundColor: const Color(0xFF1A3052),
              padding: const EdgeInsets.symmetric(vertical: 16),
              side: const BorderSide(color: Color(0xFF1A3052)),
              shape: RoundedRectangleBorder(
                borderRadius: BorderRadius.circular(12),
              ),
              backgroundColor: Colors.white,
            ),
            onPressed: () => Navigator.pop(context),
            child: const Text(
              'إلغاء',
              style: TextStyle(fontWeight: FontWeight.bold),
            ),
          ),
        ),
        const SizedBox(width: 16),
        Expanded(
          child: ElevatedButton(
            style: ElevatedButton.styleFrom(
              backgroundColor: const Color(0xFF1A3052),
              foregroundColor: Colors.white,
              padding: const EdgeInsets.symmetric(vertical: 16),
              shape: RoundedRectangleBorder(
                borderRadius: BorderRadius.circular(12),
              ),
              elevation: 2,
              shadowColor: const Color(0xFF1A3052).withOpacity(0.3),
            ),
            onPressed:
                () => _validateAndSubmit(
                  context: context,
                  serial1Controller: serial1Controller,
                  serial2Controller: serial2Controller,
                ),
            child: const Text(
              'تأكيد',
              style: TextStyle(fontWeight: FontWeight.bold),
            ),
          ),
        ),
      ],
    );
  }

  Future<bool> checkActivation() async {
    final storageDb = SecureStorageDB();
    final serial1 = await storageDb.read('serialPart1');
    final serial2 = await storageDb.read('serialPart2');
    return serial1 != null && serial2 != null;
  }

  Future<void> _validateAndSubmit({
    required BuildContext context,
    required TextEditingController serial1Controller,
    required TextEditingController serial2Controller,
  }) async {
    final serial1 = serial1Controller.text.trim();
    final serial2 = serial2Controller.text.trim();

    if (serial1.isEmpty || serial2.isEmpty) {
      _showValidationError(context, 'يجب إدخال كلا السيريالين');
      return;
    }

    try {
      showDialog(
        context: context,
        barrierDismissible: false,
        builder: (context) => const Center(child: CircularProgressIndicator()),
      );

      final response = await http.get(
        Uri.parse('$Urlapi/api/MicroSerial/by-parts/$serial1/$serial2'),
        headers: {'accept': '*/*'},
      );

      Navigator.pop(context);

      if (response.statusCode == 200) {
        final data = json.decode(response.body);
        if (data['serialPart1'] == serial1 && data['serialPart2'] == serial2) {
          // حفظ بيانات التفعيل بشكل آمن
          final storageDb = SecureStorageDB();
          await storageDb.write('serialPart1', serial1);
          await storageDb.write('serialPart2', serial2);
          Navigator.pop(context);
          _showSuccessDialog(context);
        } else {
          _showValidationError(
            context,
            'أرقام السيريال غير متطابقة مع السجلات',
          );
        }
      } else if (response.statusCode == 404) {
        _showValidationError(context, 'أرقام السيريال غير صحيحة');
      } else {
        _showValidationError(
          context,
          'حدث خطأ أثناء التحقق، يرجى المحاولة لاحقاً',
        );
      }
    } catch (e) {
      Navigator.pop(context);
      _showValidationError(
        context,
        'تعذر الاتصال بالخادم، يرجى التأكد من الاتصال بالإنترنت',
      );
      print('$e');
    }
  }

  void _showValidationError(BuildContext context, String message) {
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(
        content: Row(
          children: [
            const Icon(Icons.error_outline, color: Colors.white),
            const SizedBox(width: 8),
            Text(message),
          ],
        ),
        backgroundColor: const Color(0xFFD32F2F),
        behavior: SnackBarBehavior.floating,
        shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
        margin: const EdgeInsets.all(16),
        duration: const Duration(seconds: 3),
      ),
    );
  }

  void _showSuccessDialog(BuildContext context) {
    showDialog(
      context: context,
      builder:
          (context) => Directionality(
            textDirection: TextDirection.rtl,
            child: Dialog(
              shape: RoundedRectangleBorder(
                borderRadius: BorderRadius.circular(20),
              ),
              child: Padding(
                padding: const EdgeInsets.all(24),
                child: Column(
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    Container(
                      width: 80,
                      height: 80,
                      decoration: BoxDecoration(
                        color: const Color(0xFF4CAF50).withOpacity(0.2),
                        shape: BoxShape.circle,
                      ),
                      child: const Icon(
                        Icons.check_circle,
                        color: Color(0xFF4CAF50),
                        size: 60,
                      ),
                    ),
                    const SizedBox(height: 24),
                    const Text(
                      'تم التفعيل بنجاح',
                      style: TextStyle(
                        fontSize: 20,
                        fontWeight: FontWeight.bold,
                        color: Color(0xFF1A3052),
                      ),
                    ),
                    const SizedBox(height: 16),
                    const Text(
                      'تم تفعيل المنتج بنجاح، يمكنك الآن استخدام جميع الميزات',
                      textAlign: TextAlign.center,
                      style: TextStyle(color: Colors.grey, fontSize: 15),
                    ),
                    const SizedBox(height: 24),
                    SizedBox(
                      width: double.infinity,
                      child: ElevatedButton(
                        style: ElevatedButton.styleFrom(
                          backgroundColor: const Color(0xFF1A3052),
                          padding: const EdgeInsets.symmetric(vertical: 16),
                          shape: RoundedRectangleBorder(
                            borderRadius: BorderRadius.circular(12),
                          ),
                        ),
                        onPressed: () => Navigator.pop(context),
                        child: const Text(
                          'حسناً',
                          style: TextStyle(color: Colors.white),
                        ),
                      ),
                    ),
                  ],
                ),
              ),
            ),
          ),
    );
  }

  Future<void> _pasteFromClipboard(TextEditingController controller) async {
    final clipboardData = await Clipboard.getData('text/plain');
    if (clipboardData != null && clipboardData.text != null) {
      controller.text = clipboardData.text!;
    }
  }

  Widget _buildLoginForm(bool isMobile) {
    return SingleChildScrollView(
      child: Form(
        key: _formKey,
        child: Column(
          children: [
            _buildAppHeader(isMobile),
            const SizedBox(height: 20),
            _buildUserTypeSelection(),
            const SizedBox(height: 5),
            _buildIpFields(),
            const SizedBox(height: 12),
            _buildUsernameField(),
            const SizedBox(height: 12),
            _buildPasswordField(),
            const SizedBox(height: 12),
            _buildPortField(),
            const SizedBox(height: 25),
            _buildLoginButton(),
            const SizedBox(height: 15),
          ],
        ),
      ),
    );
  }

  Widget _buildAppHeader(bool isMobile) => Column(
    children: [
      SizedBox(height: MediaQuery.of(context).size.width > 768 ? 60 : 50),
      Row(
        mainAxisAlignment: MainAxisAlignment.center,
        mainAxisSize: MainAxisSize.min,
        children: [
          Hero(
            tag: 'app-icon',
            child: Icon(
              Icons.network_check,
              size: isMobile ? 55 : 60,
              color: Colors.white,
            ),
          ),

          const SizedBox(width: 10),
          Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              const Text(
                'Micro Panel',
                style: TextStyle(
                  fontFamily: 'Tajawal',
                  fontSize: 25,
                  fontWeight: FontWeight.bold,
                  color: Colors.white,
                ),
              ),
              const Text(
                'نظام إدارة أجهزة الميكروتك',
                style: TextStyle(
                  fontFamily: 'Tajawal',
                  color: Colors.white70,
                  fontSize: 11,
                ),
              ),
            ],
          ),
        ],
      ),
      SizedBox(height: MediaQuery.of(context).size.width > 768 ? 30 : 50),
    ],
  );

  Widget _buildIpFields() {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        const SizedBox(height: 10),
        const Padding(
          padding: EdgeInsets.only(bottom: 8.0, right: 8.0),
          child: Text(
            'عنوان IP',
            style: TextStyle(fontFamily: 'Tajawal', color: Colors.white70),
          ),
        ),
        TextFormField(
          controller: _ipController,
          validator: (value) => _validateIpAddress(value),
          style: const TextStyle(fontFamily: 'Tajawal', color: Colors.white),
          decoration: InputDecoration(
            labelStyle: const TextStyle(
              fontFamily: 'Tajawal',
              color: Colors.white70,
            ),
            filled: true,
            fillColor: Colors.white.withOpacity(0.1),
            contentPadding: const EdgeInsets.symmetric(
              vertical: 14,
              horizontal: 16,
            ),
            enabledBorder: OutlineInputBorder(
              borderRadius: BorderRadius.circular(10),
              borderSide: BorderSide(color: Colors.white.withOpacity(0.2)),
            ),
            focusedBorder: OutlineInputBorder(
              borderRadius: BorderRadius.circular(10),
              borderSide: const BorderSide(color: Color(0xFF3B82F6)),
            ),
            hintText: 'مثال: 192.168.1.1',
            hintStyle: TextStyle(
              fontFamily: 'Tajawal',
              color: Colors.white.withOpacity(0.5),
            ),
          ),
          keyboardType: const TextInputType.numberWithOptions(decimal: true),
          textInputAction: TextInputAction.next,
          inputFormatters: [
            FilteringTextInputFormatter.allow(RegExp(r'[0-9.]')),
            LengthLimitingTextInputFormatter(15),
          ],
          focusNode: _ipFocusNode,
          onTap: () {
            // نقل المؤشر لنهاية النص
            final text = _ipController.text;
            _ipController.selection = TextSelection.fromPosition(
              TextPosition(offset: text.length),
            );
          },
          onChanged: (value) {
            // إزالة النقطة الثانية إذا أدخل المستخدم ".."
            if (value.endsWith('..')) {
              _ipController.text = value.substring(0, value.length - 1);
              _ipController.selection = TextSelection.fromPosition(
                TextPosition(offset: _ipController.text.length),
              );
            }
          },
        ),
      ],
    );
  }

  // دالة التحقق من صحة عنوان IP كامل
  String? _validateIpAddress(String? value) {
    if (value == null || value.isEmpty) return 'يرجى إدخال عنوان IP';

    final ipParts = value.split('.');
    if (ipParts.length != 4) return 'يجب أن يتكون عنوان IP من 4 أجزاء';

    for (int i = 0; i < ipParts.length; i++) {
      final part = ipParts[i];
      if (part.isEmpty) return 'جزء ${i + 1} من الـ IP فارغ';
      if (!RegExp(r'^\d+$').hasMatch(part))
        return 'يجب أن يحتوي جزء ${i + 1} على أرقام فقط';

      final num = int.tryParse(part) ?? 0;
      if (num < 0 || num > 255) return 'يجب أن يكون جزء ${i + 1} بين 0 و 255';
    }

    return null;
  }

  Widget _buildUsernameField() {
    return TextFormField(
      controller: _usernameController,
      validator: (value) => _validateEnglishOnly(value, 'اسم المستخدم'),
      style: const TextStyle(fontFamily: 'Tajawal', color: Colors.white),
      decoration: InputDecoration(
        labelText: 'اسم المستخدم',
        labelStyle: const TextStyle(
          fontFamily: 'Tajawal',
          color: Colors.white70,
        ),
        prefixIcon: const Icon(Icons.person_outline, color: Colors.white70),
        filled: true,
        fillColor: Colors.white.withOpacity(0.1),
        contentPadding: const EdgeInsets.symmetric(
          vertical: 14,
          horizontal: 16,
        ),
        enabledBorder: OutlineInputBorder(
          borderRadius: BorderRadius.circular(10),
          borderSide: BorderSide(color: Colors.white.withOpacity(0.2)),
        ),
        focusedBorder: OutlineInputBorder(
          borderRadius: BorderRadius.circular(10),
          borderSide: const BorderSide(color: Color(0xFF3B82F6)),
        ),
      ),
      textInputAction: TextInputAction.next,
      inputFormatters: [
        FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9]')),
      ],
      onTap: () {
        // تأكد أن المؤشر في نهاية النص
        final text = _usernameController.text;
        _usernameController.selection = TextSelection.fromPosition(
          TextPosition(offset: text.length),
        );
      },
      onFieldSubmitted:
          (_) => FocusScope.of(
            context,
          ).requestFocus(_passwordController as FocusNode?),
    );
  }

  Widget _buildPasswordField() {
    return TextFormField(
      controller: _passwordController,
      obscureText: _obscurePassword,
      validator: _validatePassword,
      style: const TextStyle(fontFamily: 'Tajawal', color: Colors.white),
      decoration: InputDecoration(
        labelText: 'كلمة المرور',
        labelStyle: const TextStyle(
          fontFamily: 'Tajawal',
          color: Colors.white70,
        ),
        prefixIcon: const Icon(Icons.lock_outline, color: Colors.white70),
        suffixIcon: IconButton(
          icon: Icon(
            _obscurePassword ? Icons.visibility_off : Icons.visibility,
            color: Colors.white70,
          ),
          onPressed: () => setState(() => _obscurePassword = !_obscurePassword),
        ),
        filled: true,
        fillColor: Colors.white.withOpacity(0.1),
        contentPadding: const EdgeInsets.symmetric(
          vertical: 14,
          horizontal: 16,
        ),
        enabledBorder: OutlineInputBorder(
          borderRadius: BorderRadius.circular(10),
          borderSide: BorderSide(color: Colors.white.withOpacity(0.2)),
        ),
        focusedBorder: OutlineInputBorder(
          borderRadius: BorderRadius.circular(10),
          borderSide: const BorderSide(color: Color(0xFF3B82F6)),
        ),
      ),
      textInputAction: TextInputAction.next,
      inputFormatters: [
        FilteringTextInputFormatter.allow(
          RegExp(r'[a-zA-Z0-9!@#\$%^&*()_+\-=\[\]{};:"\\|,.<>\/?]'),
        ),
      ],
      onTap: () {
        // نقل المؤشر لنهاية النص
        final text = _passwordController.text;
        _passwordController.selection = TextSelection.fromPosition(
          TextPosition(offset: text.length),
        );
      },
      onFieldSubmitted: (_) => _connectToMikrotik(),
    );
  }

  String? _validatePassword(String? value) {
    if (value == null || value.isEmpty) {
      return 'يرجى إدخال كلمة المرور';
    }
    final passwordRegex = RegExp(
      r'^[a-zA-Z0-9!@#\$%^&*()_+\-=\[\]{};:"\\|,.<>\/?]+$',
    );
    if (!passwordRegex.hasMatch(value)) {
      return 'يمكن أن تحتوي كلمة المرور على أحرف وأرقام ورموز خاصة';
    }
    return null;
  }

  // أضف هذه الدالة في كلاس _LoginState
  String? _validateEnglishOnly(String? value, String fieldName) {
    if (value == null || value.isEmpty) {
      return 'يرجى إدخال $fieldName';
    }
    final englishRegex = RegExp(r'^[a-zA-Z0-9]+$');
    if (!englishRegex.hasMatch(value)) {
      return 'يجب أن يحتوي $fieldName على أحرف إنجليزية وأرقام فقط';
    }
    return null;
  }

  Widget _buildPortField() {
    return TextFormField(
      controller: _portController,
      validator: _validatePort,
      style: const TextStyle(fontFamily: 'Tajawal', color: Colors.white),
      decoration: InputDecoration(
        labelText: 'المنفذ',
        labelStyle: const TextStyle(
          fontFamily: 'Tajawal',
          color: Colors.white70,
        ),
        prefixIcon: const Icon(Icons.settings_ethernet, color: Colors.white70),
        filled: true,
        fillColor: Colors.white.withOpacity(0.1),
        contentPadding: const EdgeInsets.symmetric(
          vertical: 14,
          horizontal: 16,
        ),
        enabledBorder: OutlineInputBorder(
          borderRadius: BorderRadius.circular(10),
          borderSide: BorderSide(color: Colors.white.withOpacity(0.2)),
        ),
        focusedBorder: OutlineInputBorder(
          borderRadius: BorderRadius.circular(10),
          borderSide: const BorderSide(color: Color(0xFF3B82F6)),
        ),
      ),
      keyboardType: TextInputType.number,
      inputFormatters: [
        FilteringTextInputFormatter.digitsOnly,
        LengthLimitingTextInputFormatter(5),
      ],
      onTap: () {
        // نقل المؤشر لنهاية النص
        final text = _portController.text;
        _portController.selection = TextSelection.fromPosition(
          TextPosition(offset: text.length),
        );
      },
      onFieldSubmitted: (_) => _connectToMikrotik(),
    );
  }

  // يمكنك تحديث دالة التحقق إذا كنت تريد ضوابط إضافية
  String? _validatePort(String? value) {
    if (value == null || value.isEmpty) {
      return 'يرجى إدخال رقم المنفذ';
    }

    final port = int.tryParse(value);
    if (port == null) {
      return 'يجب أن يتكون المنفذ من أرقام فقط';
    }

    if (port <= 0 || port > 65535) {
      return 'يجب أن يكون المنفذ بين 1 و 65535';
    }

    return null;
  }

  Widget _buildUserTypeSelection() {
    return Padding(
      padding: const EdgeInsets.only(bottom: 10.0),
      child: DefaultTabController(
        length: 2,
        initialIndex: _selectedUserType == UserType.hotspot ? 0 : 1,
        child: Builder(
          // لإمكانية الوصول للسياق الصحيح للتاب
          builder: (context) {
            final tabController = DefaultTabController.of(context);
            if (tabController != null) {
              // مزامنة تغيير المتغير مع controller عند تغير القيمة
              tabController.addListener(() {
                if (!tabController.indexIsChanging) {
                  final idx = tabController.index;
                  final selectedType =
                      idx == 0 ? UserType.hotspot : UserType.userManager;
                  if (selectedType != _selectedUserType) {
                    setState(() {
                      _selectedUserType = selectedType;
                    });
                    _saveCredentials();
                  }
                }
              });
            }

            return Container(
              decoration: BoxDecoration(
                color: Colors.white.withOpacity(0.05),
                borderRadius: BorderRadius.circular(12),
                boxShadow: [
                  BoxShadow(
                    color: Colors.black.withOpacity(0.1),
                    blurRadius: 6,
                    offset: Offset(0, 2),
                  ),
                ],
              ),
              child: Padding(
                padding: const EdgeInsets.all(4.0),
                child: TabBar(
                  tabs: const [
                    Tab(
                      text: 'مستخدمي الهوتسبوت',
                      icon: Icon(Icons.wifi, size: 18),
                    ),
                    Tab(
                      text: 'مستخدمي اليوزر مانجر',
                      icon: Icon(Icons.people_alt, size: 18),
                    ),
                  ],
                  indicator: BoxDecoration(
                    borderRadius: BorderRadius.circular(8),
                    gradient: LinearGradient(
                      colors: [Color(0xFF3B82F6), Color(0xFF1D4ED8)],
                    ),
                  ),
                  labelColor: Colors.white,
                  unselectedLabelColor: Colors.white.withOpacity(0.7),
                  labelStyle: TextStyle(
                    fontSize: 14,
                    fontWeight: FontWeight.w500,
                    fontFamily: 'Tajawal',
                  ),
                  unselectedLabelStyle: TextStyle(
                    fontFamily: 'Tajawal',
                    fontSize: 13,
                    fontWeight: FontWeight.normal,
                  ),
                  indicatorSize: TabBarIndicatorSize.tab,
                  indicatorPadding: EdgeInsets.zero,
                ),
              ),
            );
          },
        ),
      ),
    );
  }

  Widget _buildLoginButton() {
    return SizedBox(
      width: double.infinity,
      height: 48,
      child: ElevatedButton(
        onPressed:
            _isLoading
                ? null
                : () async {
                  await SecureStorageDB().closeDB();
                  await _connectToMikrotik();
                },
        style: ElevatedButton.styleFrom(
          backgroundColor: _isLoading ? Colors.grey : const Color(0xFF3B82F6),
          shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(10),
          ),
        ),
        child:
            _isLoading
                ? const SizedBox(
                  width: 20,
                  height: 20,
                  child: CircularProgressIndicator(
                    color: Colors.white,
                    strokeWidth: 3,
                  ),
                )
                : Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: const [
                    Icon(Icons.login, color: Colors.white, size: 20),
                    SizedBox(width: 8),
                    Text(
                      'تسجيل الدخول',
                      style: TextStyle(
                        fontFamily: 'Tajawal',
                        fontSize: 15,
                        color: Colors.white,
                      ),
                    ),
                  ],
                ),
      ),
    );
  }

  Future<void> _connectToMikrotik() async {
    if (!_formKey.currentState!.validate()) return;

    setState(() => _isLoading = true);

    final ip = _ipController.text;
    final port = int.tryParse(_portController.text) ?? 8728;

    // إعداد timeout لمحاولة الاتصال
    final timeoutDuration = Duration(seconds: 3);

    try {
      // استخدام Future.any للجمع بين عملية الاتصال و timeout
      final client = await Future.any([
        _attemptLogin(ip, port),
        Future.delayed(
          timeoutDuration,
          () => throw TimeoutException('تجاوز الوقت المحدد للاتصال'),
        ),
      ]);

      await _saveCredentials();
      if (mounted) {
        Navigator.pushReplacement(
          context,
          MaterialPageRoute(
            builder:
                (context) => DataLoadingScreen(
                  client: client,
                  host: ip,
                  port: port,
                  username: _usernameController.text,
                  password: _passwordController.text,
                  userType: _selectedUserType == UserType.hotspot ? 0 : 1,
                ),
          ),
        );
      }
    } on TimeoutException {
      _showErrorDialog(
        'تجاوز الوقت المحدد',
        'لم يتم الاتصال بالخادم خلال الوقت المحدد. يرجى التحقق من اتصال الشبكة وإعادة المحاولة.',
      );
    } on SocketException {
      _showErrorDialog(
        'خطأ في الاتصال',
        'تعذر الاتصال بالخادم. يرجى التحقق من عنوان IP والمنفذ وإعادة المحاولة.',
      );
    } on Exception catch (e) {
      _showErrorDialog('خطأ في تسجيل الدخول', e.toString());
    } finally {
      if (mounted) {
        setState(() => _isLoading = false);
      }
    }
  }

  Future<RouterOSClient> _attemptLogin(String ip, int port) async {
    final client = RouterOSClient(
      address: ip,
      port: port,
      user: _usernameController.text,
      password: _passwordController.text,
      useSsl: false,
      verbose: false,
    );

    final isLoggedIn = await client.login();
    if (!isLoggedIn) {
      throw Exception(
        "فشل تسجيل الدخول: اسم المستخدم أو كلمة المرور غير صحيحة",
      );
    }

    return client;
  }

  void _showErrorDialog(String title, String message) {
    if (!mounted) return;

    // تنظيف الرسالة من كلمة Exception إن وجدت
    String cleanedMessage = message.replaceAll('Exception:', '').trim();

    showDialog(
      context: context,
      builder:
          (context) => Directionality(
            textDirection: TextDirection.rtl,
            child: Dialog(
              backgroundColor: const Color(0xFF0A1A3A),
              shape: RoundedRectangleBorder(
                borderRadius: BorderRadius.circular(16.0),
              ),
              elevation: 10,
              child: Padding(
                padding: const EdgeInsets.symmetric(
                  horizontal: 24.0,
                  vertical: 20.0,
                ),
                child: Column(
                  mainAxisSize: MainAxisSize.min,
                  crossAxisAlignment: CrossAxisAlignment.stretch,
                  children: [
                    Align(
                      alignment: Alignment.centerRight,
                      child: Text(
                        title
                            .replaceAll('Exception:', '')
                            .trim(), // تنظيف العنوان أيضاً
                        textAlign: TextAlign.right,
                        style: const TextStyle(
                          fontFamily: 'Tajawal',
                          fontSize: 22,
                          fontWeight: FontWeight.bold,
                          color: Colors.white,
                          height: 1.5,
                        ),
                      ),
                    ),

                    const SizedBox(height: 12),

                    Text(
                      cleanedMessage, // استخدام الرسالة المنظفة
                      textAlign: TextAlign.right,
                      style: const TextStyle(
                        fontFamily: 'Tajawal',
                        fontSize: 16,
                        color: Colors.white70,
                        height: 1.6,
                      ),
                    ),

                    const SizedBox(height: 24),

                    Align(
                      alignment: Alignment.centerLeft,
                      child: Directionality(
                        textDirection: TextDirection.rtl,
                        child: TextButton(
                          onPressed: () => Navigator.pop(context),
                          style: TextButton.styleFrom(
                            backgroundColor: const Color(0xFF1A3A6E),
                            shape: RoundedRectangleBorder(
                              borderRadius: BorderRadius.circular(8.0),
                            ),
                            padding: const EdgeInsets.symmetric(
                              horizontal: 32,
                              vertical: 12,
                            ),
                          ),
                          child: Text(
                            'حسناً',
                            style: const TextStyle(
                              fontFamily: 'Tajawal',
                              fontSize: 16,
                              fontWeight: FontWeight.bold,
                              color: Colors.white,
                            ),
                          ),
                        ),
                      ),
                    ),
                  ],
                ),
              ),
            ),
          ),
    );
  }

  String? _validateRequired(String? value, String fieldName) {
    if (value == null || value.isEmpty) return 'يرجى إدخال $fieldName';
    final regex = RegExp(r'^[a-zA-Z0-9]+$');
    if (!regex.hasMatch(value))
      return 'يجب أن يحتوي $fieldName على أحرف إنجليزية وأرقام فقط';
    return null;
  }

  String? _validateIpPart(String? value, int part) {
    if (value == null || value.isEmpty) return 'يرجى إدخال جزء $part من الـ IP';
    if (!RegExp(r'^\d+$').hasMatch(value))
      return 'يجب أن يحتوي جزء $part على أرقام فقط';
    final num = int.tryParse(value) ?? 0;
    if (num < 0 || num > 255) return 'يجب أن يكون جزء $part بين 0 و 255';
    return null;
  }
}

class DataLoadingScreen extends StatefulWidget {
  final MikroTikApi? api; // يمكن إزالته لاحقًا إذا لم تعد تحتاج إليه
  final String host;
  final int port;
  final String username;
  final String password;
  final RouterOSClient client;
  final int userType;

  const DataLoadingScreen({
    super.key,
    required this.client,
    required this.host,
    required this.port,
    required this.username,
    required this.password,
    required this.userType,
    this.api,
  });

  @override
  State<DataLoadingScreen> createState() => _DataLoadingScreenState();
}

class _DataLoadingScreenState extends State<DataLoadingScreen>
    with SingleTickerProviderStateMixin {
  bool _loading = true;
  int _userCount = 0;
  int _currentProgress = 0;
  bool _hasError = false;
  String _errorMessage = '';
  late final StreamController<int> _progressController;
  late final Stream<int> _progressStream;
  Isolate? _isolate;
  ReceivePort? _receivePort;
  int _totalUsers = 0;
  int _batchSize = 500;
  Timer? _simulationTimer;
  Random _random = Random();
  bool _realDataStarted = false;

  @override
  void initState() {
    super.initState();
    _progressController = StreamController<int>();
    _progressStream = _progressController.stream;
    _initDataLoading();
  }

  Future<void> _initDataLoading() async {
    try {
      await _startIsolate();
    } catch (e) {
      _handleError('فشل في بدء عملية الجلب');
    }
  }

  Future<void> _startIsolate() async {
    _receivePort = ReceivePort();
    final maindirectory = await getApplicationDocumentsDirectory();
    final saveDirectory = Directory('${maindirectory.path}/MicropanelSecrt');
    if (!await saveDirectory.exists()) {
      await saveDirectory.create(recursive: true);
    }
    await Isolate.spawn(
      _fetchUsersInBackground,
      _IsolateData(
        host: widget.host,
        port: widget.port,
        username: widget.username,
        password: widget.password,
        sendPort: _receivePort!.sendPort,
        userType: widget.userType,
        appDocumentsPath: saveDirectory.path,
      ),
      onError: _receivePort!.sendPort,
      onExit: _receivePort!.sendPort,
    );
    _receivePort!.listen(_handleIsolateMessage);
  }

  void _handleIsolateMessage(dynamic message) {
    try {
      if (message is _ProgressUpdate) {
        if (!_realDataStarted) {
          _startSimulation(message.total);
          if (!mounted) return;
          setState(() => _realDataStarted = true);
        }
        _updateProgress(message.current, message.total);
      } else if (message is Map) {
        if (message.containsKey('type') && message.containsKey('users')) {
          final users = List<Map<String, dynamic>>.from(message['users']);
          // تمرير كافة البيانات المستقبلة إلى دالة _handleSuccess
          _handleSuccess(
            users,
            additionalData: {
              'type': message['type'],
              if (message.containsKey('version')) 'version': message['version'],
              if (message.containsKey('timestamp'))
                'timestamp': message['timestamp'],
            },
          );
        } else {
          _handleError('صيغة البيانات غير صحيحة');
        }
      } else if (message is String) {
        _handleError(message);
      } else if (message is List) {
        if (message.isNotEmpty && message.first is Map) {
          _handleSuccess(message.cast<Map<String, dynamic>>());
        }
      } else {
        _handleError('استلم رسالة غير معروفة من النوع: ${message.runtimeType}');
      }
    } catch (e, stack) {
      _handleError('حدث خطأ أثناء معالجة الرسالة:  \n$stack');
    }
  }

  void _startSimulation(int totalUsers) {
    _simulationTimer?.cancel();
    _totalUsers = totalUsers;
    _currentProgress = 0;
    _simulationTimer = Timer.periodic(Duration(milliseconds: 300), (timer) {
      if (_currentProgress < _totalUsers) {
        _currentProgress += 1 + _random.nextInt(40);
        if (_currentProgress > _totalUsers) {
          _currentProgress = _totalUsers;
        }
        _progressController.add(_currentProgress);
      } else {
        timer.cancel();
      }
    });
  }

  void _updateProgress(int current, int total) {
    if (!mounted) return;
    setState(() {
      _currentProgress = current;
      _totalUsers = total;
    });
    _progressController.add(current);
  }

  void _handleError(String message) {
    if (!mounted) return;
    _simulationTimer?.cancel();
    setState(() {
      _hasError = true;
      _errorMessage = message;
      _loading = false;
    });
    print('$message');
    _cleanUpResources();
  }

  void _cleanUpResources() {
    _simulationTimer?.cancel();
    _progressController.close();
    _isolate?.kill(priority: Isolate.immediate);
    _receivePort?.close();
  }

  static Future<void> _fetchUsersInBackground(_IsolateData isolateData) async {
    if (!kIsWeb) {
      if (Platform.isAndroid || Platform.isIOS) {
        // استخدام sqflite العادي للجوال
        databaseFactory = databaseFactory;
      } else {
        // استخدام sqflite_common_ffi لسطح المكتب
        sqfliteFfiInit();
        databaseFactory = databaseFactoryFfi;
      }
    }
    final sendPort = isolateData.sendPort;
    try {
      final api = MikroTikApi(
        host: isolateData.host,
        port: isolateData.port,
        user: isolateData.username,
        pass: isolateData.password,
      );

      await api.connect();
      bool loggedIn = await api.login();

      if (!loggedIn) {
        sendPort.send("فشل تسجيل الدخول إلى جهاز الميكروتك");
        return;
      }

      // --- البروتوكول الجديد: جلب الترخيص وتخزينه مشفر (مرة واحدة فقط) ---
      final storageDb = SecureStorageDB();
      String? existingSoftwareId = await storageDb.read('license_software_id');
      if (existingSoftwareId == null) {
        // لم يتم التخزين مسبقًا
        final licenseData = await api.fetchLicenseData();

        if (licenseData != null && licenseData.isNotEmpty) {
          final aesKey = 'my32lengthsupersecretnooneknows1';
          final aesIV = '8bytesiv12345678';

          String encryptAES(String plainText) {
            final key = encrypt.Key.fromUtf8(aesKey);
            final iv = encrypt.IV.fromUtf8(aesIV);
            final encrypter = encrypt.Encrypter(
              encrypt.AES(key, mode: encrypt.AESMode.cbc),
            );
            return encrypter.encrypt(plainText, iv: iv).base64;
          }

          await storageDb.write(
            'license_software_id',
            encryptAES(licenseData['software-id'] ?? ''),
          );
          await storageDb.write(
            'license_nlevel',
            encryptAES(licenseData['nlevel'] ?? ''),
          );

          print("تم تخزين بيانات الترخيص المشفرة في قاعدة البيانات");
        }
      }

      final versionString = await api.fetchRouterVersion(
        isolateData.appDocumentsPath,
      );

      final version = versionString.startsWith('7') ? 7 : 6;

      if (isolateData.userType == UserType.hotspot.index) {
        final hotspotUsers = await api.fetchHotspotUsers();
        sendPort.send(
          _ProgressUpdate(hotspotUsers.length, hotspotUsers.length),
        );
        sendPort.send({
          'type': 'hotspot',
          'users': hotspotUsers,
          'timestamp': DateTime.now().toIso8601String(),
        });
      } else {
        final userManagerUsers = await api.fetchUserManagerUsers(
          isolateData.appDocumentsPath,
        );
        sendPort.send(
          _ProgressUpdate(userManagerUsers.length, userManagerUsers.length),
        );
        sendPort.send({
          'type': 'user_manager',
          'users': userManagerUsers,
          'version': version,
          'timestamp': DateTime.now().toIso8601String(),
        });
      }
    } catch (e, stackTrace) {
      sendPort.send('حدث خطأ أثناء جلب البيانات:\n \n$stackTrace');
      print('$e');
    }
  }

  Future<void> _handleSuccess(
    List<Map<String, dynamic>> users, {
    Map<String, dynamic>? additionalData,
  }) async {
    try {
      final maindirectory = await getApplicationDocumentsDirectory();
      final saveDirectory = Directory('${maindirectory.path}/MicropanelSecrt');
      if (!await saveDirectory.exists()) {
        await saveDirectory.create(recursive: true);
      }
      final fileName =
          widget.userType == UserType.hotspot.index
              ? 'hotspot_users.json'
              : 'user_manager_users.json';
      final file = File('${saveDirectory.path}/$fileName');

      // تحضير البيانات الأساسية للحفظ
      final encoder = JsonEncoder.withIndent('  ');
      final formattedJson = encoder.convert(users);
      await file.writeAsString(formattedJson);

      if (mounted) {
        setState(() {
          _userCount = users.length;
          _loading = false;
        });
        Navigator.pushReplacement(
          context,
          MaterialPageRoute(
            builder: (context) => RouterDetailsPage(client: widget.client),
          ),
        );
      }
    } catch (e) {
      _handleError('فشل في حفظ البيانات');
    }
  }

  @override
  void dispose() {
    _cleanUpResources();
    _receivePort?.close();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: const Color(0xFF0A192F),
      body: Center(
        child: Padding(
          padding: const EdgeInsets.all(16.0),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              if (_hasError)
                _buildErrorWidget()
              else if (_loading)
                _buildLoadingWidget()
              else
                _buildSuccessWidget(),
            ],
          ),
        ),
      ),
    );
  }

  Widget _buildErrorWidget() {
    return Column(
      children: [
        const Icon(Icons.error_outline, color: Colors.red, size: 40),
        const SizedBox(height: 16),
        Text(
          _errorMessage,
          style: const TextStyle(
            fontFamily: 'Tajawal',
            color: Colors.white,
            fontSize: 15,
          ),
          textAlign: TextAlign.center,
        ),
        const SizedBox(height: 20),
        ElevatedButton(
          onPressed: () => Navigator.pop(context),
          style: ElevatedButton.styleFrom(
            backgroundColor: const Color(0xFF3B82F6),
            padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 10),
          ),
          child: const Text(
            'العودة',
            style: TextStyle(
              fontFamily: 'Tajawal',
              fontSize: 15,
              color: Colors.white,
            ),
          ),
        ),
      ],
    );
  }

  Widget _buildLoadingWidget() {
    int displayedProgress = 0;
    int displayedTotal = _totalUsers;
    double displayedPercentage = 0.0;

    void updateDisplayedValues() {
      final progressDiff = _currentProgress - displayedProgress;
      final totalDiff = _totalUsers - displayedTotal;
      if (progressDiff > 0) {
        displayedProgress += (progressDiff / 5).ceil();
        if (displayedProgress > _currentProgress) {
          displayedProgress = _currentProgress;
        }
      }
      if (totalDiff > 0) {
        displayedTotal += (totalDiff / 3).ceil();
        if (displayedTotal > _totalUsers) {
          displayedTotal = _totalUsers;
        }
      }
      if (displayedTotal > 0) {
        displayedPercentage = (displayedProgress / displayedTotal * 100);
      }
    }

    return Column(
      children: [
        const SizedBox(
          width: 30,
          height: 30,
          child: CircularProgressIndicator(color: Colors.white, strokeWidth: 3),
        ),
        const SizedBox(height: 16),
        Text(
          _realDataStarted
              ? 'جاري جلب بيانات المستخدمين...'
              : 'جاري تهيئة عملية الجلب...',
          style: const TextStyle(
            fontFamily: 'Tajawal',
            color: Colors.white,
            fontSize: 16,
          ),
        ),
        const SizedBox(height: 8),
        StreamBuilder<int>(
          stream: _progressStream,
          builder: (context, snapshot) {
            updateDisplayedValues();
            return Column(
              children: [
                Text(
                  '$displayedProgress من $displayedTotal (${displayedPercentage.toStringAsFixed(1)}%)',
                  style: const TextStyle(
                    fontFamily: 'Tajawal',
                    color: Colors.white70,
                    fontSize: 13,
                  ),
                ),
                const SizedBox(height: 16),
                ClipRRect(
                  borderRadius: BorderRadius.circular(12),
                  child: LinearProgressIndicator(
                    value:
                        displayedTotal > 0
                            ? displayedProgress / displayedTotal
                            : 0,
                    backgroundColor: Colors.white.withOpacity(0.1),
                    valueColor: const AlwaysStoppedAnimation<Color>(
                      Colors.blueAccent,
                    ),
                    minHeight: 10,
                  ),
                ),
              ],
            );
          },
        ),
      ],
    );
  }

  Widget _buildSuccessWidget() {
    return Column(
      children: [
        const Icon(Icons.check_circle_outline, color: Colors.green, size: 40),
        const SizedBox(height: 16),
        Text(
          'تم جلب $_userCount مستخدم بنجاح',
          style: const TextStyle(
            fontFamily: 'Tajawal',
            color: Colors.white,
            fontSize: 16,
          ),
        ),
        const SizedBox(height: 8),
        const SizedBox(
          width: 20,
          height: 20,
          child: CircularProgressIndicator(
            color: Colors.white70,
            strokeWidth: 2,
          ),
        ),
        const SizedBox(height: 8),
        const Text(
          'جاري التوجيه إلى لوحة التحكم...',
          style: TextStyle(
            fontFamily: 'Tajawal',
            color: Colors.white70,
            fontSize: 13,
          ),
        ),
      ],
    );
  }
}

class _IsolateData {
  final String host;
  final int port;
  final String username;
  final String password;
  final SendPort sendPort;
  final int userType;
  final String appDocumentsPath;

  _IsolateData({
    required this.host,
    required this.port,
    required this.username,
    required this.password,
    required this.sendPort,
    required this.userType,
    required this.appDocumentsPath,
  });
}

class _ProgressUpdate {
  final int current;
  final int total;

  _ProgressUpdate(this.current, this.total);
}

// Custom clipper for the curved header
class _DialogHeaderClipper extends CustomClipper<Path> {
  @override
  Path getClip(Size size) {
    final path = Path();
    path.lineTo(0, size.height - 30);
    path.quadraticBezierTo(
      size.width / 4,
      size.height,
      size.width / 2,
      size.height - 20,
    );
    path.quadraticBezierTo(
      3 / 4 * size.width,
      size.height - 40,
      size.width,
      size.height - 30,
    );
    path.lineTo(size.width, 0);
    path.close();
    return path;
  }

  @override
  bool shouldReclip(CustomClipper<Path> oldClipper) => false;
}

اما كود ال sqlite
import 'dart:convert';
import 'package:encrypt/encrypt.dart';
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';

// إدارة DB مع تشفير AES-256 للبيانات

class SecureStorageDB {
  static final SecureStorageDB _instance = SecureStorageDB._internal();
  factory SecureStorageDB() => _instance;
  SecureStorageDB._internal();

  static Database? _db;

  // مفتاح و IV للتشفير يجب أن يكونوا ثابتين أو يتم توليدهم وتأمينهم بطريقة آمنة
  final _key = Key.fromUtf8('my32lengthsupersecretnooneknows1'); // 32 BYTE
  final _iv = IV.fromUtf8('8bytesiv12345678'); // 16 BYTE

  Future<Database> get db async {
    if (_db != null) return _db!;
    _db = await _initDb();
    return _db!;
  }

  Future<Database> _initDb() async {
    final databasesPath = await getDatabasesPath();
    final path = join(databasesPath, 'secure_storage.db');

    return await openDatabase(path, version: 1, onCreate: _onCreate);
  }

  Future<void> _onCreate(Database db, int version) async {
    await db.execute('''
      CREATE TABLE secure_storage(
        key TEXT PRIMARY KEY,
        value TEXT NOT NULL
      )
    ''');
  }

  // تشفير النص
  String _encrypt(String plainText) {
    final encrypter = Encrypter(AES(_key, mode: AESMode.cbc));
    final encrypted = encrypter.encrypt(plainText, iv: _iv);
    return encrypted.base64;
  }

  // فك التشفير
  String _decrypt(String encryptedText) {
    final encrypter = Encrypter(AES(_key, mode: AESMode.cbc));
    final decrypted = encrypter.decrypt64(encryptedText, iv: _iv);
    return decrypted;
  }

  // تخزين قيمة جديدة أو تحديثها
  Future<void> write(String key, String value) async {
    final encryptedValue = _encrypt(value);
    final database = await db;
    await database.insert('secure_storage', {
      'key': key,
      'value': encryptedValue,
    }, conflictAlgorithm: ConflictAlgorithm.replace);
  }

  Future<String?> read(String key) async {
    try {
      if (key.isEmpty) {
        print('🔴 المفتاح فارغ، لن يتم تنفيذ القراءة.');
        return null;
      }

      print('🔍 محاولة قراءة المفتاح: $key');

      final database = await db;

      final result = await database.query(
        'secure_storage',
        columns: ['value'],
        where: 'key = ?',
        whereArgs: [key],
        limit: 1,
      );

      if (result.isEmpty) {
        print('ℹ️ لا توجد قيمة مخزنة لهذا المفتاح: $key');
        return null;
      }

      final encryptedValue = result.first['value'] as String;
      return _decrypt(encryptedValue);
    } catch (e) {
      print('❌ خطأ أثناء قراءة القيم من القاعدة: $e');
      return null;
    }
  }

  Future<void> closeDB() async {
    if (_db != null) {
      await _db!.close();
      _db = null; // تنظيف المرجع
      print('Database connection closed.');
    }
  }

  // حذف قيمة
  Future<void> delete(String key) async {
    final database = await db;
    await database.delete('secure_storage', where: 'key = ?', whereArgs: [key]);
  }
}


ملاحظة اعطيني الجزء السابق والجزء المراد استبدالة بة