import 'dart:io';

import 'package:flutter/cupertino.dart';
import 'package:get/get.dart';
import 'package:injectable/injectable.dart';
import 'package:keyboard/base/base_controller.dart';
import 'package:keyboard/data/api/request/intimacy_analyze_request.dart';
import 'package:keyboard/data/bean/upload_info.dart';
import 'package:keyboard/data/repository/account_repository.dart';
import 'package:keyboard/resource/string.gen.dart';
import 'package:keyboard/utils/error_handler.dart';
import 'package:keyboard/utils/string_format_util.dart';
import 'package:keyboard/utils/toast_util.dart';
import 'package:keyboard/utils/upload/upload_scene_type.dart';
import 'package:keyboard/utils/upload/upload_state.dart';
import 'package:wechat_assets_picker/wechat_assets_picker.dart';
import '../../../data/api/request/intimacy_generate_character_request.dart';
import '../../../data/api/response/intimacy_analyze_config_response.dart';
import '../../../data/api/response/intimacy_analyze_response.dart';
import '../../../data/api/response/user_info_response.dart';
import '../../../data/bean/ai_model.dart';
import '../../../data/bean/keyboard_info.dart';
import '../../../data/bean/member_info.dart';
import '../../../data/bean/option_select_config.dart';
import '../../../data/bean/option_select_item.dart';
import '../../../data/repository/intimacy_analyze_repository.dart';
import '../../../data/repository/keyboard_repository.dart';
import '../../../dialog/loading_dialog.dart';
import '../../../router/app_page_arguments.dart';
import '../../../utils/atmob_log.dart';
import '../../../utils/http_handler.dart';
import '../../../utils/image_picker_util.dart';
import '../../../utils/intimacy_analyze_config_helper.dart';
import '../../../utils/upload/upload_file_manager.dart';
import '../../profile/profile_page.dart';
import '../../store/new_discount/new_discount_page.dart';
import '../../store/store_page.dart';
import 'dialog/direction/custom_direction_edit_dialog.dart';
import 'dialog/intimacy_generate_character/intimacy_generate_character_edit_dialog.dart';

/// 亲密度分析上传页Controller
@injectable
class IntimacyAnalyseUploadController extends BaseController {
  final String tag = "IntimacyAnalyseUploadController";

  /// 上传场景
  final UploadSceneType uploadSceneType = UploadSceneType.intimacyAnalyse;

  /// 用户信息
  final AccountRepository accountRepository;

  /// 亲密度分析Repository
  IntimacyAnalyzeRepository intimacyAnalyzeRepository;

  /// 键盘信息Repository
  KeyboardRepository keyboardRepository;

  /// 亲密度分析帮助类
  IntimacyAnalyzeConfigHelper intimacyAnalyzeConfigHelper;

  /// 文件上传管理器
  UploadFileManager uploadFileManager;

  /// 亲密度配置
  Rxn<IntimacyAnalyzeConfigResponse> get intimacyAnalyzeConfig =>
      intimacyAnalyzeRepository.intimacyAnalyzeConfig;

  /// 上传图片列表
  RxList<UploadInfo> uploadInfoList = <UploadInfo>[].obs;

  /// Ai模型列表
  RxList<AiModel> aiModelList = <AiModel>[].obs;

  /// 当前应用的Ai模型
  Rxn<AiModel> currentAiModel = Rxn();

  /// 预测方向的选项列表
  RxList<OptionSelectConfig> directionOptionSelectConfigList =
      <OptionSelectConfig>[].obs;

  /// 是否上传页
  RxBool isUploadPage = true.obs;

  /// 是否可以自定义方向
  RxBool isCanCustomDirection = false.obs;

  /// 当前用户信息
  Rxn<UserInfoResponse> get userInfo => accountRepository.userInfo;

  /// 当前用户的会员
  Rxn<MemberInfo> get memberInfo => accountRepository.memberStatusInfo;

  /// 报告是否生成中
  Rx<bool> isResultGenerating = false.obs;

  /// 当前键盘信息
  Rxn<KeyboardInfo> get currentKeyboardInfo =>
      keyboardRepository.chooseKeyboardInfo;

  /// 当前选择的预测方向
  Rx<String> currentDirectionOption = "".obs;

  /// 亲密分析结果
  Rxn<IntimacyAnalyzeResponse> intimacyAnalyzeResult = Rxn();

  IntimacyAnalyseUploadController(
    this.intimacyAnalyzeRepository,
    this.intimacyAnalyzeConfigHelper,
    this.uploadFileManager,
    this.accountRepository,
    this.keyboardRepository,
  );

  @override
  void onInit() {
    super.onInit();
    _initArgs();
  }

  @override
  void onReady() {
    super.onReady();
    updateIntimacyAnalyzeConfig(intimacyAnalyzeConfig.value);
  }

  /// 更新亲密度配置
  void updateIntimacyAnalyzeConfig(IntimacyAnalyzeConfigResponse? config) {
    isCanCustomDirection.value = (config != null ? config.custom : false)!;
    _initDirectionOptionSelectConfigList(config);
    _initAiModelList(config);
  }

  /// 初始化预测方向选项列表
  void _initDirectionOptionSelectConfigList(
    IntimacyAnalyzeConfigResponse? config,
  ) {
    List<OptionSelectConfig> newList =
        config?.direction?.map((item) {
          var title = item.title ?? "";
          var iconUrl = item.iconUrl ?? "";
          var optionList =
              item.options?.map((value) {
                return OptionSelectItem(value, value);
              }).toList() ??
              [];
          return OptionSelectConfig(title, iconUrl, optionList);
        }).toList() ??
        [];
    directionOptionSelectConfigList.clear();
    directionOptionSelectConfigList.addAll(newList);
  }

  /// 初始化Ai模型列表
  void _initAiModelList(IntimacyAnalyzeConfigResponse? config) {
    List<AiModel> newModelList = config?.modes?.toList() ?? [];
    aiModelList.clear();
    aiModelList.addAll(newModelList);

    // 默认取第一个作为选中项
    if (newModelList.isNotEmpty) {
      currentAiModel.value = aiModelList.first;
    }
  }

  /// 初始化参数
  void _initArgs() {
    final arguments = Get.arguments as Map<String, dynamic>?;

    /// 当前选择的图片列表
    List<AssetEntity> selectedAssetList = [];
    if (arguments?[AppPageArguments.selectedAssetList] == null) {
      AtmobLog.i(tag, '没有传递 selectedAssetList 参数');
    } else {
      final List<AssetEntity>? argumentList =
          arguments?[AppPageArguments.selectedAssetList] as List<AssetEntity>?;
      if (argumentList != null) {
        selectedAssetList.assignAll(argumentList);
        AtmobLog.i(tag, "selectedAssetList: $selectedAssetList");
      }
    }

    _handleSelectedAssetUpload(selectedAssetList.toList());
  }

  /// 处理一进页面，就开始上传
  void _handleSelectedAssetUpload(List<AssetEntity> selectedAssetList) async {
    for (var entity in selectedAssetList) {
      // 获取文件路径
      File? file = await entity.file;
      if (file == null) {
        continue;
      }
      // 添加到上传列表
      uploadInfoList.add(
        uploadFileManager.uploadFile(
          sceneType: uploadSceneType,
          file: file,
          onUploadInfoUpdateCallback: (uploadInfo) {
            // 上传信息更新时回调，更新UI
            _updateUploadInfo(uploadInfo);
          },
          onUploadFailCallback: (error) {
            // 接口业务异常
            if (error is ServerErrorException) {
              ErrorHandler.toastError(error);
            } else {
              // 其他异常
              ErrorHandler.toastError(
                error,
                message: StringName.noUploadScreenshotTip,
              );
            }
          },
        ),
      );
      uploadInfoList.refresh();
    }
  }

  /// 是否正在上传
  bool _isUploading() {
    var list = uploadInfoList.toList();

    for (var item in list) {
      if (item.uploadState == UploadState.uploading.state) {
        return true;
      }
    }

    return false;
  }

  /// 更新上传信息
  void _updateUploadInfo(UploadInfo uploadInfo) {
    // 更新上传信息
    var newList = [...uploadInfoList];
    newList.map((item) {
      if (item.id == uploadInfo.id) {
        return uploadInfo;
      }
      return item;
    }).toList();
    uploadInfoList.value = newList;
  }

  /// 删除上传信息
  void deleteUploadInfo(UploadInfo uploadInfo) {
    uploadFileManager.deleteUploadInfo(uploadInfo);
    uploadInfoList.removeWhere((item) {
      return item.id == uploadInfo.id;
    });
    uploadInfoList.refresh();
  }

  /// 返回上一页
  void clickBack() {
    uploadFileManager.deleteUploadInfoBySceneType(uploadSceneType);
    Get.back();
  }

  /// 点击上传按钮
  void clickUploadBtn(BuildContext context) async {
    // 计算还可以上传多少张图片
    int count =
        intimacyAnalyzeConfigHelper.getMaxAssetsCount() - uploadInfoList.length;

    // 跳转到图片选择，并返回选择的图片列表
    List<AssetEntity>? selectedAssetList = await ImagePickerUtil.pickImage(
      context,
      maxAssetsCount: count,
    );
    // 选择了新图片，触发上传
    if (selectedAssetList?.isNotEmpty == true) {
      _handleSelectedAssetUpload(selectedAssetList!);
    }
  }

  /// 切换Ai模型
  void switchAiModel(AiModel newAiModel) {
    currentAiModel.value = newAiModel;
    currentAiModel.refresh();
  }

  /// 添加预测方向
  void addDirection() {
    // 弹出预测方向的编辑弹窗
    CustomDirectionEditDialog.show((String customDirection) {
      // 新增一行自定义预测方向的配置项
      bool firstRowConfigIsCustom =
          directionOptionSelectConfigList.firstOrNull?.isCustom ?? false;
      if (directionOptionSelectConfigList.isEmpty || !firstRowConfigIsCustom) {
        // 没有自定义配置，添加一个
        directionOptionSelectConfigList[0] = OptionSelectConfig("", "", [
          OptionSelectItem(customDirection, customDirection),
        ], isCustom: true);
      } else {
        // 已经有一个，在原来的基础上，添加1个
        OptionSelectConfig oldConfig = directionOptionSelectConfigList[0];
        oldConfig.options.add(
          OptionSelectItem(customDirection, customDirection),
        );
      }
      directionOptionSelectConfigList.refresh();
    });
  }

  /// 预测方向，选中选项
  void selectDirectionOption(
    OptionSelectConfig rowConfig,
    OptionSelectItem optionItem,
  ) {
    // 更新当前选中项
    currentDirectionOption.value = optionItem.name;

    // 将所有预测方向都反选
    for (var config in directionOptionSelectConfigList) {
      config.options =
          config.options.map((ele) {
            ele.selected = false;
            return ele;
          }).toList();
    }
    // 再勾选当前的选中项
    optionItem.selected = true;
    // 由于Rx响应式变量，无法监听对象中嵌套对象的某个属性的变化，导致页面不会刷新，需要手动刷新页面
    directionOptionSelectConfigList.refresh();
  }

  /// 点击了正在分析中按钮
  void clickAnalysingBtn() {
    if (isResultGenerating.value) {
      ToastUtil.show(StringName.intimacyAnalyseIngPleaseWait);
    }
  }

  /// 点击了下一步按钮
  /// [isNeedForceVip] 是否强制需要VIP
  void clickNextBtn(bool isNeedForceVip) async {
    // 是否VIP
    bool isVip = accountRepository.memberStatusInfo.value?.isMember ?? false;

    if (isNeedForceVip) {
      // 非Vip，跳转到会员活动页
      if (!isVip) {
        ToastUtil.show(StringName.needVipTip);
        NewDiscountPage.start();
        return;
      }
    }

    // 正在上传，禁止操作
    if (_isUploading()) {
      ToastUtil.show(StringName.uploadingTip);
      return;
    }

    // 上传的图片后端地址
    List<String> imageList =
        uploadInfoList.map((item) {
          return item.fileBackendPath ?? "";
        }).toList();
    // 键盘Id
    String keyboardId = currentKeyboardInfo.value?.id ?? "";
    // 预测方向
    String direction = currentDirectionOption.value;
    // 当前选择的Ai模型
    String aiModel = currentAiModel.value?.value ?? "";

    if (imageList.isEmpty) {
      ToastUtil.show(StringName.noUploadScreenshotTip);
      return;
    }
    if (keyboardId.isEmpty) {
      ToastUtil.show(StringName.noChooseIntimacyTaTip);
      return;
    }
    if (direction.isEmpty) {
      ToastUtil.show(StringName.noChoosePredictionDirectionTip);
      return;
    }
    if (aiModel.isEmpty) {
      ToastUtil.show(StringName.noChooseAiModelTip);
      return;
    }

    // 切换到报告生成中
    isUploadPage.value = false;
    isResultGenerating.value = true;

    // 非Vip，实现一个假的生成中，然后创建一个模糊的报告内容
    if (!isVip) {
      Future.delayed(Duration(milliseconds: 4000), () {
        isResultGenerating.value = false;
      });
      return;
    }

    try {
      // 分析亲密度
      IntimacyAnalyzeResponse response = await intimacyAnalyzeRepository
          .getIntimacyAnalyze(
            IntimacyAnalyzeRequest(imageList, keyboardId, direction, aiModel),
          );

      AtmobLog.d(tag, "分析亲密度 => ${response.toJson()}");

      isResultGenerating.value = false;
      intimacyAnalyzeResult.value = response;
    } catch (error) {
      isResultGenerating.value = false;
      AtmobLog.e(tag, error.toString());
      if (error is ServerErrorException) {
        // 需要Vip权限
        if (error.code == 1005) {
          ToastUtil.show(error.message);
          NewDiscountPage.start();
        } else {
          ToastUtil.show(error.message);
        }
      } else {
        ErrorHandler.toastError(error);
      }
    }
  }

  /// 换Ta测测
  void switchTaTest() async {
    // 跳转到档案选择页，获取当前的键盘Id
    KeyboardInfo? keyboardInfo = await ProfilePage.start() as KeyboardInfo?;
    AtmobLog.d(tag, "switchTaTest result：=> ${keyboardInfo?.toJson() ?? ""}");
    currentKeyboardInfo.value = keyboardInfo;
  }

  /// 点击生成定制人设按钮
  void clickGenerateCharacterBtn() {
    // 键盘Id
    String keyboardId = currentKeyboardInfo.value?.id ?? "";
    // 聊天策略
    String chatStrategy = intimacyAnalyzeResult.value?.chatStrategy ?? "";

    // 弹出生成亲密度人设的编辑弹窗
    IntimacyGenerateCharacterEditDialog.show((String name) async {
      // 调用生成接口
      try {
        await intimacyAnalyzeRepository.intimacyCharacterGenerate(
          IntimacyGenerateCharacterRequest(keyboardId, name, chatStrategy),
        );
        // 获取我的用户信息和Ta的用户信息
        String myName = userInfo.value?.name ?? "";
        // 对方用户的头像
        String taName = currentKeyboardInfo.value?.name ?? "";
        ToastUtil.show(
          StringFormatUtil.formatStrArr(
            StringName.intimacyGenerateCharacterAddSuccess,
            [myName, taName],
          ),
        );
      } catch (e) {
        ErrorHandler.toastError(
          e,
          message: StringName.intimacyGenerateCharacterAddFail,
        );
      }
    });
  }
}
