import 'dart:io';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:rasadyar_app/data/model/app_info_model.dart';
import 'package:rasadyar_app/infrastructure/utils/local_storage_utils.dart';
import 'package:rasadyar_core/core.dart';

class SplashLogic extends GetxController with GetTickerProviderStateMixin {
  late final AnimationController scaleController;
  late final AnimationController rotateController;
  Rxn<Animation<double>> scaleAnimation = Rxn();
  Rxn<Animation<double>> rotationAnimation = Rxn();
  RxBool hasUpdated = false.obs;
  RxBool onUpdateDownload = false.obs;
  RxDouble percent = 0.0.obs;
  final RxnString _updateFilePath = RxnString();
  final platform = MethodChannel('apk_installer');
  final Dio _dio = Dio();
  var gService = Get.find<GService>();
  var tokenService = Get.find<TokenStorageService>();

  AppInfoModel? appInfoModel;

  @override
  void onInit() {
    super.onInit();
    scaleController = AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 1500),
    );

    rotateController = AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 8000),
    );

    scaleAnimation.value = Tween<double>(begin: 0.8, end: 1.2).animate(scaleController);

    rotationAnimation.value = Tween<double>(begin: 0.0, end: 1).animate(rotateController);

    rotateController.forward();
    rotateController.addStatusListener((status) {
      if (status == AnimationStatus.completed) {
        rotateController.repeat();
      } else if (status == AnimationStatus.dismissed) {
        rotateController.forward();
      }
    });

    scaleController.forward();
    scaleController.addStatusListener((status) {
      if (status == AnimationStatus.completed) {
        scaleController.reverse();
      } else if (status == AnimationStatus.dismissed) {
        scaleController.forward();
      }
    });

    hasUpdated.listen((data) {
      if (data) {
        requiredUpdateDialog(
          onConfirm: () async {
            await fileDownload();
          },
        );
      } else if (!data && Get.isDialogOpen == true) {
        Get.back();
      }
    });
    onUpdateDownload.listen((data) {
      hasUpdated.value = false;
      if (data) {
        Get.bottomSheet(
          isDismissible: false,
          isScrollControlled: true,
          backgroundColor: Colors.transparent,
          Container(
            height: 170,
            decoration: const BoxDecoration(
              color: Colors.white,
              borderRadius: BorderRadius.vertical(top: Radius.circular(16.0)),
            ),
            padding: const EdgeInsets.all(16.0),
            child: Column(
              mainAxisSize: MainAxisSize.min,
              spacing: 8,
              children: [
                const Text('در حال دانلود بروزرسانی برنامه...'),
                Obx(
                  () => Row(
                    spacing: 8,
                    children: [
                      Expanded(
                        child: LinearProgressIndicator(
                          value: percent.value,
                          color: AppColor.greenNormal,
                          minHeight: 4,
                        ),
                      ),
                      SizedBox(
                        width: 55.w,
                        child: Text(
                          '${(percent.value * 100).toStringAsFixed(2)}%',
                          textAlign: TextAlign.center,
                        ),
                      ),
                    ],
                  ),
                ),

                Row(
                  spacing: 8,
                  children: [
                    Expanded(
                      child: ObxValue((data) {
                        return RElevated(
                          backgroundColor: AppColor.greenNormal,
                          height: 40.h,
                          onPressed: data.value != null
                              ? () {
                                  installApk();
                                  Get.back();
                                }
                              : null,
                          text: 'نصب',
                        );
                      }, _updateFilePath),
                    ),
                    Expanded(
                      child: ROutlinedElevated(
                        borderColor: AppColor.error,
                        text: 'خروج',
                        onPressed: () async {
                          exit(0);
                        },
                      ),
                    ),
                  ],
                ),
              ],
            ),
          ),
        );
      }
    });
  }

  @override
  void onReady() {
    super.onReady();

    Future.delayed(const Duration(milliseconds: 250), () async {
      try {
        final isUpdateNeeded = await checkVersion();
        if (isUpdateNeeded) return;

        final module = gService.getSelectedModule();
        final target = gService.getTargetPage(module);
        if (module != null) {
          tokenService.setGlobalTokenAndRefToken(module);
        }

        if (target != null) {
          var mFuns = getFunctionsList(target.functions);
          await Future.wait(mFuns ?? []);

          iLog("target.route ===>${target.route!}");
          Get.offAndToNamed(target.route!);
        }
      } catch (e, st) {
        eLog("onReady error: $e\n$st");
      }
    });
  }

  @override
  void onClose() {
    rotateController.dispose();
    scaleController.dispose();
    super.onClose();
  }

  Future<bool> checkVersion() async {
    try {
      final info = await PackageInfo.fromPlatform();
      int version = info.version.versionNumber;
      var res = await _dio.get("https://rsibackend.rasadyaar.ir/app/apk-info/");

      appInfoModel = AppInfoModel.fromJson(res.data);

      if ((appInfoModel?.info?.version?.versionNumber ?? 0) > version) {
        hasUpdated.value = !hasUpdated.value;
        return true;
      }
      return false;
    } catch (e) {
      return false;
    }
  }

  Future<void> fileDownload() async {
    onUpdateDownload.value = true;
    final dir = await getApplicationDocumentsDirectory();
    final filePath = "${dir.path}/rasadyar.apk";
    final file = File(filePath);
    if (await file.exists()) {
      await file.delete();
    }
    int attempts = 0;
    int retryCount = 4;
    bool success = false;

    while (attempts < retryCount && !success) {
      try {
        await _dio.download(
          appInfoModel?.download_link ?? '',
          filePath,
          onReceiveProgress: (count, total) {
            if (total != -1 && total > 0) {
              percent.value = count / total;
            }
          },
        );
        success = true;
      } on DioException catch (e) {
        attempts++;
        percent.value = 0.0;
        if (attempts >= retryCount) {
          eLog("Download failed after $attempts attempts: ${e.message}");
        } else {
          await Future.delayed(const Duration(milliseconds: 1200));
        }
      }
    }

    if (success) {
      _updateFilePath.value = filePath;
    }

    onUpdateDownload.value = false;
  }

  Future<void> installApk() async {
    try {
      eLog(_updateFilePath.value);
      await platform.invokeMethod('apk_installer', {'appPath': _updateFilePath.value});
    } catch (e) {
      eLog(e);
    }
  }
}
