import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:keyboard/resource/colors.gen.dart';

import '../../../../data/bean/ai_model.dart';
import '../../../../resource/assets.gen.dart';
import '../../../../widget/gradient_text.dart';

/// 选择新的Ai模型时回调
typedef OnChooseAiModelCallback = void Function(AiModel newAiModel);

/// Ai模型选择Popup锚点弹窗
class AiModelSelectPopup {
  /// 用于标识弹窗的唯一性
  static const _tag = "AiModelSelectPopup";

  /// 弹窗是否显示中
  static bool _isShowing = false;

  /// 弹窗是否显示中
  static bool isShowing() {
    return _isShowing;
  }

  /// 显示
  /// [anchorBtnKey] 锚点按钮的GlobalKey
  /// [aiModelList] 模型列表
  /// [currentAiModel] 当前使用的模型
  /// [onChooseAiModelCallback] 选择新的Ai模型时回调
  static void show(
    GlobalKey anchorBtnKey,
    BuildContext context, {
    required List<AiModel> aiModelList,
    required AiModel currentAiModel,
    required OnChooseAiModelCallback onChooseAiModelCallback,
  }) {
    if (_isShowing) {
      return;
    }

    double popupWidth = 145.w;

    SmartDialog.showAttach(
      // 绑定唯一tag
      tag: _tag,
      // 绑定锚点的BuildContext，才能确定弹窗的显示位置
      targetContext: context,
      // 在锚点的顶部显示
      alignment: _calculateBestAlignment(anchorBtnKey, context),
      // 使用动画
      useAnimation: true,
      // 动画类型
      animationType: SmartAnimationType.fade,
      // 是否允许事件穿透
      usePenetrate: false,
      // 透明遮罩
      maskColor: ColorName.transparent,
      // 监听弹窗关闭
      onDismiss: () {
        _isShowing = false;
      },
      // 位置偏移配置
      targetBuilder: (Offset targetOffset, Size targetSize) {
        // 获取锚点信息
        final anchorRenderBox =
            anchorBtnKey.currentContext!.findRenderObject() as RenderBox;
        final anchorPosition = anchorRenderBox.localToGlobal(Offset.zero);
        final anchorSize = anchorRenderBox.size;

        // 计算X轴的偏移量，距离屏幕左边有一段距离
        double leftOffset = 6.w;
        double popupX =
            anchorPosition.dx +
            (anchorSize.width / 2) -
            (popupWidth / 2) +
            leftOffset;

        // 计算Y轴的偏移量（默认是在按钮的上边显示，UI设计要求盖着按钮，所以需要增加偏移量）
        double bottomOffset = 46.h;
        double popupY = anchorPosition.dy + bottomOffset;

        return Offset(popupX, popupY);
      },
      // 构建弹窗内容
      builder: (_) {
        return Container(
          // 固定弹窗的宽度
          width: popupWidth,
          decoration: BoxDecoration(
            color: ColorName.white,
            border: Border.all(
              color: ColorName.bgAiModelSwitchBorderBtn,
              width: 1.0.w,
            ),
            borderRadius: BorderRadius.all(Radius.circular(16.r)),
          ),
          child: Column(
            // 包裹内容
            mainAxisSize: MainAxisSize.min,
            children: [
              SizedBox(height: 12.h),
              // Ai模型列表
              Flexible(
                child: ListView.builder(
                  // ListView包裹内容
                  shrinkWrap: true,
                  physics: const ClampingScrollPhysics(),
                  // 去除默认padding
                  padding: EdgeInsets.zero,
                  itemCount: aiModelList.length,
                  itemBuilder: (BuildContext context, int index) {
                    AiModel itemData = aiModelList[index];
                    return _buildListItem(
                      index,
                      itemData,
                      currentAiModel == itemData,
                      onChooseAiModelCallback,
                    );
                  },
                ),
              ),
              // 当前选中项
              _buildCurrentAiModelItem(currentAiModel),
            ],
          ),
        );
      },
    );

    // 设置为正在显示中
    _isShowing = true;
  }

  /// 计算对齐方式
  static Alignment _calculateBestAlignment(
    GlobalKey anchorBtnKey,
    BuildContext context,
  ) {
    final renderBox =
        anchorBtnKey.currentContext?.findRenderObject() as RenderBox;
    final position = renderBox.localToGlobal(Offset.zero);
    final screenHeight = MediaQuery.of(context).size.height;

    return position.dy > screenHeight / 2
        ? Alignment.topCenter
        : Alignment.bottomCenter;
  }

  /// 列表项
  static Widget _buildListItem(
    int index,
    AiModel itemData,
    bool isSelected,
    OnChooseAiModelCallback onChooseAiModelCallback,
  ) {
    return GestureDetector(
      onTap: () {
        onChooseAiModelCallback(itemData);
        SmartDialog.dismiss();
      },
      child: Container(
        margin: EdgeInsets.only(left: 6.w, right: 6.w, bottom: 10.h),
        padding: EdgeInsets.symmetric(vertical: 8.h),
        decoration: BoxDecoration(
          borderRadius: BorderRadius.circular(7.r),
          color: isSelected ? ColorName.bgAiModelSelected : ColorName.white,
        ),
        child: Center(
          child: Text(
            itemData.name ?? "",
            style: TextStyle(
              color: ColorName.black80,
              fontSize: 14.sp,
              fontWeight: isSelected ? FontWeight.w500 : FontWeight.w400,
            ),
          ),
        ),
      ),
    );
  }

  /// 当前选中项
  static Widget _buildCurrentAiModelItem(AiModel currentAiModel) {
    return GestureDetector(
      onTap: () {
        dismiss();
      },
      child: Container(
        padding: EdgeInsets.symmetric(vertical: 8.h, horizontal: 14.w),
        child: Row(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            // 文字
            GradientText(
              colors: [
                ColorName.aiModelSwitchBtnColor1,
                ColorName.aiModelSwitchBtnColor2,
              ],
              child: Text(
                currentAiModel.name ?? "",
                style: TextStyle(fontSize: 14.sp, fontWeight: FontWeight.w500),
              ),
            ),
            SizedBox(width: 8.w),
            // 箭头
            Assets.images.iconModeSwitchArrow.image(width: 15.w, height: 15.w),
          ],
        ),
      ),
    );
  }

  /// 隐藏
  static void dismiss() {
    if (!_isShowing) {
      return;
    }
    SmartDialog.dismiss(tag: _tag);
  }
}
