import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:in_app_review/in_app_review.dart';
import 'package:mypoint_flutter_app/extensions/string_extension.dart';
import 'package:mypoint_flutter_app/networking/restful_api_client_all_request.dart';
import 'package:mypoint_flutter_app/preference/data_preference.dart';
import 'package:mypoint_flutter_app/widgets/alert/popup_data_model.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:uuid/uuid.dart';
import '../configs/constants.dart';
import '../base/app_navigator.dart';
import '../networking/restful_api_viewmodel.dart';
import '../screen/pageDetail/model/detail_page_rule_type.dart';
import '../screen/pipi/pipi_detail_screen.dart';
import '../screen/webview/web_view_screen.dart';
import '../shared/router_gage.dart';
import 'directional_action_type.dart';

class Defines {
  static const String actionType = 'click_action_type';
  static const String actionParams = 'click_action_param';
}

class DirectionalScreen {
  final String? clickActionType;
  final String? clickActionParam;
  final PopupDataModel? popup;

  const DirectionalScreen._({this.clickActionType, this.clickActionParam, this.popup});

  factory DirectionalScreen.fromJson(Map<String, dynamic> json) => DirectionalScreen._(
    clickActionType: json['click_action_type'] as String?,
    clickActionParam: json['click_action_param'] as String?,
    popup: json['popup'] != null ? PopupDataModel.fromJson(json['popup'] as Map<String, dynamic>) : null,
  );

  Map<String, dynamic> toJson() => {'click_action_type': clickActionType, 'click_action_param': clickActionParam};

  static DirectionalScreen? build({String? clickActionType, String? clickActionParam}) {
    if ((clickActionType ?? "").isEmpty) return null;
    if (clickActionType == "VIEW_APP_SCREEN") {
      return DirectionalScreen._(clickActionType: clickActionParam, clickActionParam: null);
    }
    return DirectionalScreen._(clickActionType: clickActionType, clickActionParam: clickActionParam);
  }

  static DirectionalScreen? buildByName({required DirectionalScreenName name, String? clickActionParam}) {
    if (name == DirectionalScreenName.appScreen) {
      return DirectionalScreen._(clickActionType: clickActionParam, clickActionParam: null);
    }
    return DirectionalScreen._(clickActionType: name.rawValue, clickActionParam: clickActionParam);
  }

  bool begin() {
    final type = DirectionalScreenNameExtension.fromRawValue(clickActionType ?? "");
    if (type == null) {
      print("Không nhận diện được action type: $clickActionType");
      return false;
    }
    switch (type) {
      case DirectionalScreenName.brand:
        if ((clickActionParam ?? '').isEmpty) return false;
        Get.toNamed(affiliateBrandDetailScreen, arguments: {"brandId": clickActionParam});
        return true;
      case DirectionalScreenName.preferentialHotList:
        Get.toNamed(vouchersScreen, arguments: {"isHotProduct": true});
        return true;
      case DirectionalScreenName.memberShip:
        Get.toNamed(membershipScreen);
        return true;
      case DirectionalScreenName.customerReviewApp:
        final storeUrl = 'https://itunes.apple.com/app/id${Constants.appStoreId}?action=write-review';
        openStringUrlExternally(storeUrl);
        return true;
      // case DirectionalScreenName.historyInvitedFriend:
      // case DirectionalScreenName.screenAddInvitationCode:
      //   // TODO: Lịch sử mời bạn – cần màn tương ứng
      //   return false;
      case DirectionalScreenName.rateStorePopup:
        _requestAppReview();
        return false;
      //   return false;
      // case DirectionalScreenName.shoppingOnline:
      // case DirectionalScreenName.partnerRedirect:
      //   return false;
      // case DirectionalScreenName.brandOffline:
      //   return false;
      case DirectionalScreenName.pipiScreen:
        Get.bottomSheet(const PipiDetailScreen(), isScrollControlled: true, backgroundColor: Colors.transparent);
        return true;
      case DirectionalScreenName.viewVoucherWithCountTime:
        final countDownSecond = int.tryParse(clickActionParam ?? '') ?? 0;
        Get.toNamed(vouchersScreen, arguments: {"countDownSecond": countDownSecond});
        return true;
      case DirectionalScreenName.popViewController:
        if (Get.isOverlaysOpen) {
          Get.back();
          return true;
        }
        if (Get.key.currentState?.canPop() == true) {
          Get.back();
          return true;
        }
        return false;
      case DirectionalScreenName.finishScreen:
        Get.until((route) => route.isFirst);
        return true;
      case DirectionalScreenName.luckyMoney:
        if (clickActionParam.orEmpty.isEmpty) return false;
        BaseWebViewInput input = BaseWebViewInput(url: clickActionParam.orEmpty.urlDecoded);
        Get.toNamed(baseWebViewScreen, arguments: input);
        return true;
      case DirectionalScreenName.privacyPolicy:
        Get.toNamed(campaignDetailScreen, arguments: {"type": DetailPageRuleType.privacyPolicy});
        return true;
      case DirectionalScreenName.termsOfUse:
        Get.toNamed(campaignDetailScreen, arguments: {"type": DetailPageRuleType.termsOfUse});
        return true;
      case DirectionalScreenName.termPolicyDecree13:
        Get.toNamed(campaignDetailScreen, arguments: {"type": DetailPageRuleType.decree});
        return true;
      case DirectionalScreenName.termPolicyDeleteAccount:
        Get.toNamed(campaignDetailScreen, arguments: {"type": DetailPageRuleType.policyDeleteAccount});
        return true;
      case DirectionalScreenName.familyMedonDetailCard:
        if ((clickActionParam ?? '').isEmpty) return false;
        Get.toNamed(healthBookCardDetail, arguments: {"id": clickActionParam});
        return false;
      case DirectionalScreenName.webviewFullScreen:
        if ((clickActionParam ?? '').isEmpty) return false;
        BaseWebViewInput input = BaseWebViewInput(url: clickActionParam ?? "", isFullScreen: true);
        Get.toNamed(baseWebViewScreen, arguments: input);
        return true;
      case DirectionalScreenName.gameCardDetail:
        if ((clickActionParam ?? '').isEmpty) return false;
        Get.toNamed(gameCardScreen, arguments: {"gameId": clickActionParam ?? ''});
        return true;
      case DirectionalScreenName.inviteFriend ||
          DirectionalScreenName.customerInviteFriend ||
          DirectionalScreenName.newInviteFriend ||
          DirectionalScreenName.inviteFriendApply:
        Get.toNamed(inviteFriendCampaignScreen);
        return true;
      case DirectionalScreenName.personal:
        Get.toNamed(personalEditScreen);
        return true;
      case DirectionalScreenName.viewSMS:
        final parts = clickActionParam.orEmpty.split('_');
        if (parts.length != 2) return false;
        final phone = parts[0].trim();
        final content = parts[1].trim();
        final contentDecoded = Uri.decodeComponent(content);
        final body = Uri.encodeComponent(contentDecoded);
        // iOS: &body=..., Android: ?body=...
        final isIOS = defaultTargetPlatform == TargetPlatform.iOS;
        final urlStr = isIOS
            ? 'sms:$phone&body=$body'
            : 'sms:$phone?body=$body';
        final uri = Uri.parse(urlStr);
        print('Mở SMS: $uri phone=$phone, content=$content');
        _openUrlExternally(uri);
        return false;
      case DirectionalScreenName.setting:
        Get.toNamed(settingScreen);
        return true;
      case DirectionalScreenName.productOwnVoucher:
        Get.toNamed(voucherDetailScreen, arguments: {"customerProductId": int.parse(clickActionParam ?? "")});
        return true;
      case DirectionalScreenName.customerSupport:
        Get.toNamed(supportScreen);
        return true;
      case DirectionalScreenName.link:
        BaseWebViewInput input = BaseWebViewInput(url: clickActionParam ?? "");
        Get.toNamed(baseWebViewScreen, arguments: input);
        return true;
      case DirectionalScreenName.website:
        Get.toNamed(campaignDetailScreen, arguments: {"id": clickActionParam ?? ""});
        return true;
      case DirectionalScreenName.gameCenter:
        Get.toNamed(vplayGameCenterScreen);
        return true;
      case DirectionalScreenName.viewAllVoucher:
        Get.toNamed(vouchersScreen, arguments: {"enableSearch": true});
        return true;
      case DirectionalScreenName.news:
        Get.toNamed(newsListScreen);
        return true;
      case DirectionalScreenName.gifts:
        Get.toNamed(achievementListScreen);
        return true;
      case DirectionalScreenName.pointHunting || DirectionalScreenName.achievement:
        Get.toNamed(achievementListScreen, arguments: true);
        return true;
      case DirectionalScreenName.myPurchaseItems || DirectionalScreenName.myPurchaseItemsWaitingList:
        Get.toNamed(myVoucherListScreen);
        return true;
      case DirectionalScreenName.orderMenu:
        Get.toNamed(orderMenuScreen);
        return true;
      case DirectionalScreenName.topup || DirectionalScreenName.mobileTopup:
        Get.toNamed(phoneTopUpScreen);
        return true;
      case DirectionalScreenName.productMobileCard:
        Get.toNamed(productMobileCardScreen);
        return true;
      case DirectionalScreenName.simService:
        BaseWebViewInput input = BaseWebViewInput(url: "https://mypoint.uudaigoicuoc.com/");
        Get.toNamed(baseWebViewScreen, arguments: input);
        return true;
      case DirectionalScreenName.mobileTopupData:
        Get.toNamed(dataNetworkServiceScreen);
        return true;
      case DirectionalScreenName.pointBack:
        Get.toNamed(affiliateTabScreen, arguments: {"can_back_button": true});
        return true;
      case DirectionalScreenName.gamesBundle:
        Get.toNamed(gameTabScreen, arguments: {"can_back_button": true});
        return true;
      case DirectionalScreenName.vnTraPackage || DirectionalScreenName.familyMedon || DirectionalScreenName.voucher:
        Get.toNamed(voucherDetailScreen, arguments: {"productId": int.parse(clickActionParam ?? "")});
        return true;
      case DirectionalScreenName.viewDeepLink || DirectionalScreenName.viewDeepLinkInApp:
        if ((clickActionParam ?? "").isEmpty) return true;
        const replaceId1 = '{{customerId}}';
        const replaceId2 = '{customerId}';
        final customerId = DataPreference.instance.profile?.workerSite?.customerId ?? "";
        String urlString = clickActionParam!.urlDecoded;
        if (urlString.contains(replaceId1)) {
          urlString = urlString.replaceAll(replaceId1, customerId);
        }
        if (urlString.contains(replaceId2)) {
          urlString = urlString.replaceAll(replaceId2, customerId);
        }
        // Parse thành Uri và thêm query aff_sub3
        Uri? uri = Uri.tryParse(urlString);
        if (uri == null) return true;
        final requestId = const Uuid().v4(); // Cần package `uuid`
        final updatedUri = uri.replace(queryParameters: {...uri.queryParameters, 'aff_sub3': requestId});
        LaunchMode mode =
            type == DirectionalScreenName.viewDeepLink ? LaunchMode.externalApplication : LaunchMode.inAppWebView;
        // forceOpen(url: updatedUri, mode: mode);
        _safeOpenUrl(updatedUri, preferred: mode);
        return true;
      case DirectionalScreenName.refundHistory:
        Get.toNamed(historyPointCashBackScreen);
        return true;
      case DirectionalScreenName.dailyCheckin || DirectionalScreenName.dailyCheckinScreen:
        Get.toNamed(dailyCheckInScreen);
        return true;
      case DirectionalScreenName.favorite:
        Get.toNamed(vouchersScreen, arguments: {"favorite": true});
        return true;
      case DirectionalScreenName.transactionHistories:
        Get.toNamed(transactionHistoryScreen);
        return true;
      case DirectionalScreenName.electricBill:
        Get.toNamed(electricPaymentScreen);
        return true;
      case DirectionalScreenName.listPaymentOfElectric:
        Get.toNamed(electricPaymentHistoryScreen);
        return true;
      case DirectionalScreenName.myVnTraPackage:
        Get.toNamed(trafficServiceScreen);
        return true;
      case DirectionalScreenName.familyHealthBook:
        Get.toNamed(healthBookScreen);
        return true;
      case DirectionalScreenName.campaignSevenDayScreen:
        Get.toNamed(campaignSevenDayScreen);
        return true;
      case DirectionalScreenName.workerProfile:
        Get.toNamed(personalEditScreen);
        return true;
      case DirectionalScreenName.surveyCampaign:
        if ((clickActionParam ?? '').isEmpty) return false;
        Get.toNamed(surveyQuestionScreen, arguments: {"quizId": clickActionParam ?? ''});
        return true;
      case DirectionalScreenName.myMobileCard:
        Get.toNamed(myMobileCardListScreen);
        return true;
      case DirectionalScreenName.bankAccountManager:
        Get.toNamed(bankAccountManagerScreen);
        return true;
      case DirectionalScreenName.pointHistory:
        Get.toNamed(historyPointScreen);
        return true;
      case DirectionalScreenName.qrCode:
        Get.toNamed(qrCodeScreen);
        return true;
      case DirectionalScreenName.makeDirectionScreen:
        if ((clickActionParam ?? '').isEmpty) return false;
        () async {
          final vm = RestfulApiViewModel();
          await vm.callApi<DirectionalScreen>(
            request: () => vm.client.getDirectionScreen(clickActionParam!),
            onSuccess: (screen, res) async {
              final popup = screen.popup;
              if (popup != null) {
                AppNavigator.showPopup(data: popup);
              } else {
                screen.begin();
              }
            },
            withLoading: true,
            showAppNavigatorDialog: false,
          );
        }();
        return true;
      default:
        print("Không nhận diện được action type: $clickActionType");
        return false;
    }
  }
}

Future<bool> forceOpen({required Uri url, LaunchMode mode = LaunchMode.platformDefault}) async {
  print("force open ${url.toString()}");
  if (await canLaunchUrl(url)) {
    await launchUrl(
      url,
      mode: LaunchMode.inAppBrowserView,
      webViewConfiguration: const WebViewConfiguration(enableJavaScript: true, headers: <String, String>{}),
    );
    return true;
  }
  return false;
}

Future<void> openStringUrlExternally(String url) async {
  final uri = Uri.parse(url);
  _openUrlExternally(uri);
}

Future<void> _openUrlExternally(Uri uri) async {
  if (await canLaunchUrl(uri)) {
    await launchUrl(uri, mode: LaunchMode.externalApplication);
  } else {
    debugPrint("⚠️ Không thể mở URL: $uri");
  }
}

Future<bool> _safeOpenUrl(Uri url, {LaunchMode preferred = LaunchMode.platformDefault}) async {
  try {
    // Nếu không mở được bằng bất kỳ hình thức nào thì dừng sớm
    if (!await canLaunchUrl(url)) return false;

    // Sắp xếp các chế độ theo ưu tiên và loại bỏ trùng lặp
    final List<LaunchMode> modes = <LaunchMode>[
      preferred,
      LaunchMode.externalApplication,
      LaunchMode.inAppBrowserView,
      LaunchMode.platformDefault,
    ];
    final Set<LaunchMode> seen = <LaunchMode>{};

    for (final mode in modes) {
      if (!seen.add(mode)) continue;
      try {
        final ok = await launchUrl(
          url,
          mode: mode,
          webViewConfiguration: const WebViewConfiguration(
            enableJavaScript: true,
            headers: <String, String>{},
          ),
        );
        if (ok) return true;
      } catch (_) {
        // thử chế độ tiếp theo
      }
    }
  } catch (_) {}
  return false;
}

Future<void> _requestAppReview() async {
  final inAppReview = InAppReview.instance;
  if (await inAppReview.isAvailable()) {
    await inAppReview.requestReview();
    return;
  }
  // Fallback mở trang app trên store
  await inAppReview.openStoreListing(appStoreId: Constants.appStoreId, microsoftStoreId: null);
}
