import 'package:flutter/material.dart';
import 'package:jwt_decoder/jwt_decoder.dart';
import 'package:get/get.dart';
import 'package:siro_admin/controller/functions/device_info.dart';
import 'package:siro_admin/views/auth/login_page.dart';

import '../../constant/box_name.dart';
import '../../constant/links.dart';
import '../../constant/info.dart';
import '../../main.dart';
import '../../print.dart';
import '../../views/admin/admin_home_page.dart';
import '../../views/widgets/snackbar.dart';
import '../admin/dashboard_controller.dart';
import '../functions/crud.dart';
import '../functions/encrypt_decrypt.dart';

class OtpHelper extends GetxController {
  static final String _sendOtpUrl =
      '${AppLink.server}/auth/otp/request.php';
  static final String _verifyOtpUrl =
      '${AppLink.server}/auth/otp/verify.php';
  static final String _checkAdminLogin =
      '${AppLink.server}/Admin/auth/login.php';

  /// إرسال OTP
  static Future<bool> sendOtp(String phoneNumber) async {
    try {
      // await CRUD().getJWT();
      final response = await CRUD().post(
        link: _sendOtpUrl,
        payload: {'receiver': phoneNumber, 'user_type': 'admin'},
      );
      // Log.print('_sendOtpUrl: ${_sendOtpUrl}');
      // Log.print('response: ${response}');
      if (response != 'failure') {
        mySnackbarSuccess('تم إرسال رمز التحقق إلى رقمك عبر WhatsApp');
        return true;
      } else {
        mySnackeBarError('حدث خطأ من الخادم. حاول مجددًا.');
        return false;
      }
    } catch (e) {
      Log.print('OTP SEND ERROR: $e');
      mySnackeBarError('حدث خطأ أثناء الإرسال: $e');
      return false;
    }
  }

  /// التحقق من OTP
  Future<void> verifyOtp(String phoneNumber, String otp) async {
    try {
      final response = await CRUD().post(
        link: _verifyOtpUrl,
        payload: {
          'phone_number': phoneNumber,
          'token_code': otp,
          'user_type': 'admin',
          'device_number': box.read(BoxName.fingerPrint) ?? ''
        },
      );

      if (response != 'failure') {
        if (response['status'] == 'success') {
          box.write(BoxName.phoneVerified, true);
          box.write(BoxName.adminPhone, phoneNumber);

          mySnackbarSuccess('تم التحقق من الرقم بنجاح');
          await checkAdminLogin();
        } else {
          mySnackeBarError(response['message'] ?? 'فشل في التحقق.');
        }
      } else {
        mySnackeBarError('فشل من الخادم. حاول مرة أخرى.');
      }
    } catch (e) {
      Log.print('OTP VERIFY ERROR: $e');
      mySnackeBarError('خطأ في التحقق: $e');
    }
  }

  /// تسجيل الدخول بكلمة المرور والبصمة
  Future<bool> loginWithPassword(String password, [String phone = '']) async {
    try {
      final fingerprint = box.read(BoxName.fingerPrint);
      final response = await CRUD().post(
        link: _checkAdminLogin,
        payload: {
          'fingerprint': fingerprint,
          'password': password,
          'phone': phone,
        },
      );

      if (response != 'failure') {
        // إذا كان الرد يتطلب OTP (السيرفر يرجعها بداخل message)
        final msg = response['message'];
        if (response['status'] == 'otp_required' ||
            (msg is Map && msg['status'] == 'otp_required')) {
          String phone = (msg is Map ? msg['phone'] : response['phone']) ?? '';
          _showOtpDialog(phone, password, fingerprint);
          return false; // ننتظر إكمال الـ OTP
        }

        // إذا نجح الدخول مباشرة
        return _handleLoginSuccess(response, password);
      } else {
        // سيقوم CRUD بإظهار الخطأ المناسب (مثل "حسابك قيد المراجعة")
        return false;
      }
    } catch (e) {
      Log.print('LOGIN ERROR: $e');
      mySnackeBarError('حدث خطأ أثناء تسجيل الدخول: $e');
      return false;
    }
  }

  /// التحقق من OTP الخاص بتسجيل الدخول
  Future<void> verifyLoginOtp(
      String phone, String otp, String password, String fingerprint) async {
    try {
      final response = await CRUD().post(
        link: '${AppLink.server}/Admin/auth/verify_login.php',
        payload: {
          'phone': phone,
          'otp': otp,
          'fingerprint': fingerprint,
        },
      );

      if (response != 'failure') {
        bool success = await _handleLoginSuccess(response, password);
        if (success) {
          try {
            if (Get.isRegistered<DashboardController>()) {
              Get.find<DashboardController>().getDashBoard();
            }
          } catch (e) {}
          Get.offAll(() => const AdminHomePage());
        }
      }
    } catch (e) {
      Log.print('OTP VERIFY LOGIN ERROR: $e');
      mySnackeBarError('خطأ في التحقق من الرمز: $e');
    }
  }

  Future<bool> _handleLoginSuccess(dynamic response, String password) async {
    final msg = response['message'];
    final data = response['admin'] ?? (msg is Map ? msg['admin'] : null);
    final jwt = response['jwt'] ?? (msg is Map ? msg['jwt'] : null);

    if (jwt != null) {
      await box.write(BoxName.jwt, c(jwt));
    }

    if (data != null) {
      if (data['id'] != null) await box.write(BoxName.driverID, data['id']);
      if (data['role'] != null) {
        String role = data['role'].toString().trim();
        await box.write('admin_role', role);
        Log.print('Admin role saved: $role');
      }
      if (data['phone'] != null)
        await box.write(BoxName.adminPhone, data['phone']);
    }

    await box.write(BoxName.phoneVerified, true);
    await box.write('admin_password', password);

    mySnackbarSuccess('تم تسجيل الدخول بنجاح');
    return true;
  }

  void _showOtpDialog(String phone, String password, String fingerprint) {
    String otpCode = '';
    Get.defaultDialog(
      title: 'رمز التحقق',
      content: Column(
        children: [
          Text('تم إرسال رمز التحقق إلى WhatsApp الخاص بك ($phone)'),
          const SizedBox(height: 16),
          TextField(
            onChanged: (val) => otpCode = val,
            keyboardType: TextInputType.number,
            decoration: const InputDecoration(
              hintText: 'أدخل الرمز هنا',
              border: OutlineInputBorder(),
            ),
          ),
        ],
      ),
      textConfirm: 'تحقق',
      confirmTextColor: Colors.white,
      onConfirm: () {
        if (otpCode.length >= 3) {
          Get.back();
          verifyLoginOtp(phone, otpCode, password, fingerprint);
        } else {
          mySnackeBarError('الرجاء إدخال رمز صحيح');
        }
      },
    );
  }

  static bool _isAutoLoginAttempted = false;

  Future<void> checkAdminLogin() async {
    final fingerprint = box.read(BoxName.fingerPrint);
    final password = box.read('admin_password');

    if (fingerprint == null || password == null) {
      Get.offAll(() => const AdminLoginPage());
      return;
    }

    // ─── أولاً: التحقق من وجود توكن JWT صالح ─────────
    // إذا وُجد توكن غير منتهي الصلاحية → ندخل مباشرة بدون استدعاء login.php
    final rawJwt = box.read(BoxName.jwt);
    if (rawJwt != null) {
      try {
        String token = r(rawJwt.toString()).split(AppInformation.addd)[0];
        if (!JwtDecoder.isExpired(token)) {
          Log.print('Valid JWT found, skipping login.php (no OTP needed)');
          Get.offAll(() => const AdminHomePage());
          return;
        }
        Log.print('JWT expired, need fresh login');
      } catch (e) {
        Log.print('JWT decode failed: \$e, need fresh login');
      }
    }

    // ─── ثانياً: لا يوجد توكن صالح → استدعاء login.php ───
    final response = await CRUD().post(
      link: _checkAdminLogin,
      payload: {
        'fingerprint': fingerprint,
        'password': password,
        'is_renewal': '1',
      },
    );

    if (response != 'failure') {
      final msg = response['message'];

      if (response['status'] == 'otp_required' ||
          (msg is Map && msg['status'] == 'otp_required')) {
        String phone = (msg is Map ? msg['phone'] : response['phone']) ?? '';
        _showOtpDialog(phone, password, fingerprint);
        return; // ننتظر إدخال رمز التحقق
      }

      if (msg is Map && msg['jwt'] != null) {
        box.write(BoxName.jwt, c(msg['jwt']));
        if (msg['admin'] != null && msg['admin']['id'] != null) {
          box.write(BoxName.driverID, msg['admin']['id']);
        }
      } else if (response['jwt'] != null) {
        box.write(BoxName.jwt, c(response['jwt']));
      }
      try {
        if (Get.isRegistered<DashboardController>()) {
          Get.find<DashboardController>().getDashBoard();
        }
      } catch (e) {}
      Get.offAll(() => const AdminHomePage());
    } else {
      Log.print('Auto-login failed, redirecting to login page');
      Get.offAll(() => const AdminLoginPage());
    }
  }

  @override
  void onInit() {
    super.onInit();
    DeviceHelper.getDeviceFingerprint().then((deviceFingerprint) {
      box.write(BoxName.fingerPrint, deviceFingerprint);
    });
    // تأجيل تنفيذ التنقل حتى تنتهي مرحلة البناء
    // ⚠️ محاولة واحدة فقط للتسجيل التلقائي لمنع الحلقة اللانهائية
    Future.microtask(() {
      if (_isAutoLoginAttempted) {
        // نحن في حلقة — نتوقف ونذهب لصفحة الدخول مباشرة
        Log.print('Auto-login already attempted, skipping to login page');
        return;
      }
      _isAutoLoginAttempted = true;

      if (box.read(BoxName.phoneVerified) == true &&
          box.read(BoxName.adminPhone) != null) {
        checkAdminLogin();
      } else {
        Get.offAll(() => AdminLoginPage());
      }
    });
  }
}
