type GuideMenuItem = {
  key: string;
  label: string;
  icon: string;
};

interface GuidePopupProperties {
  show: boolean;
  title: string;
  subtitle: string;
  images: string[];
  amount: string;
}

interface GuidePopupData {
  mounted: boolean;
  visible: boolean;
  displayName: string;
  displaySubtitle: string;
  avatarUrl: string;
  avatarLetter: string;
  balanceLabel: string;
  withdrawText: string;
  incomeText: string;
  menuItems: GuideMenuItem[];
}

interface GuidePopupInstance
  extends WechatMiniprogram.Component.TrivialInstance {
  data: GuidePopupData;
  properties: GuidePopupProperties;
  _hideTimer?: number | null;
}

const DEFAULT_NAME = "当前用户";
const DEFAULT_ENTRY = "个人中心";
const DEFAULT_BALANCE_LABEL = "可提现金额";
const DEFAULT_WITHDRAW_TEXT = "立即提现";
const DEFAULT_INCOME_TEXT = "收益明细";
const HIDE_DELAY = 280;

const DEFAULT_MENU_ITEMS: GuideMenuItem[] = [
  {
    key: "orders",
    label: "我的订单",
    icon: "./icons/orders.svg",
  },
  {
    key: "prize-records",
    label: "中奖记录",
    icon: "./icons/gift.svg",
  },
  {
    key: "coupons",
    label: "我的优惠券",
    icon: "./icons/coupon.svg",
  },
  {
    key: "comment-board",
    label: "评论记录板",
    icon: "./icons/comment.svg",
  },
  {
    key: "nickname",
    label: "修改昵称",
    icon: "./icons/edit.svg",
  },
  {
    key: "complaint",
    label: "投诉",
    icon: "./icons/warning.svg",
  },
];

function normalizeImages(value: unknown): string[] {
  if (!Array.isArray(value)) return [];

  return value.filter(
    (item): item is string => typeof item === "string" && item.length > 0,
  );
}

function syncViewModel(
  instance: GuidePopupInstance,
  titleText: string,
  subtitleText: string,
  imageList: string[],
) {
  const name = titleText || wx.getStorageSync("userName") || DEFAULT_NAME;
  const subtitle = subtitleText || DEFAULT_ENTRY;
  const avatarUrl = imageList.length ? imageList[0] : "";
  const avatarLetter = String(name).trim().slice(0, 1).toUpperCase() || "U";

  instance.setData({
    displayName: name,
    displaySubtitle: subtitle,
    avatarUrl,
    avatarLetter,
  });
}

function clearHideTimer(instance: GuidePopupInstance) {
  if (!instance._hideTimer) return;

  clearTimeout(instance._hideTimer);
  instance._hideTimer = null;
}

function togglePopup(instance: GuidePopupInstance, show: boolean) {
  clearHideTimer(instance);

  if (show) {
    if (instance.data.mounted) {
      wx.nextTick(() => {
        instance.setData({ visible: true });
      });
      return;
    }

    instance.setData(
      {
        mounted: true,
        visible: false,
      },
      () => {
        wx.nextTick(() => {
          instance.setData({ visible: true });
        });
      },
    );
    return;
  }

  if (!instance.data.mounted) return;

  instance.setData({ visible: false });
  instance._hideTimer = setTimeout(() => {
    instance.setData({ mounted: false });
    instance._hideTimer = null;
  }, HIDE_DELAY);
}

Component({
  properties: {
    show: {
      type: Boolean,
      value: false,
      observer(this: GuidePopupInstance, nextValue: boolean) {
        togglePopup(this, !!nextValue);
      },
    },
    title: {
      type: String,
      value: "",
      observer(this: GuidePopupInstance, nextValue: string) {
        syncViewModel(
          this,
          nextValue || "",
          this.properties.subtitle || "",
          normalizeImages(this.properties.images),
        );
      },
    },
    subtitle: {
      type: String,
      value: "",
      observer(this: GuidePopupInstance, nextValue: string) {
        syncViewModel(
          this,
          this.properties.title || "",
          nextValue || "",
          normalizeImages(this.properties.images),
        );
      },
    },
    images: {
      type: Array,
      value: [],
      observer(this: GuidePopupInstance, nextValue: unknown) {
        syncViewModel(
          this,
          this.properties.title || "",
          this.properties.subtitle || "",
          normalizeImages(nextValue),
        );
      },
    },
    amount: {
      type: String,
      value: "0.00",
    },
  },

  data: {
    mounted: false,
    visible: false,
    displayName: DEFAULT_NAME,
    displaySubtitle: DEFAULT_ENTRY,
    avatarUrl: "",
    avatarLetter: "U",
    balanceLabel: DEFAULT_BALANCE_LABEL,
    withdrawText: DEFAULT_WITHDRAW_TEXT,
    incomeText: DEFAULT_INCOME_TEXT,
    menuItems: DEFAULT_MENU_ITEMS,
  } as GuidePopupData,

  lifetimes: {
    attached(this: GuidePopupInstance) {
      syncViewModel(
        this,
        this.properties.title || "",
        this.properties.subtitle || "",
        normalizeImages(this.properties.images),
      );
      togglePopup(this, !!this.properties.show);
    },

    detached(this: GuidePopupInstance) {
      clearHideTimer(this);
    },
  },

  methods: {
    noop() {},

    handleClose(this: GuidePopupInstance) {
      this.triggerEvent("close");
    },

    handlePreviewAvatar(this: GuidePopupInstance) {
      const images = normalizeImages(this.properties.images);
      if (!images.length) return;

      wx.previewImage({
        current: images[0],
        urls: images,
      });
    },

    handleQuickAction(
      this: GuidePopupInstance,
      e: WechatMiniprogram.CustomEvent,
    ) {
      const key = (e.currentTarget.dataset as { key?: string }).key || "";
      if (!key) return;

      this.triggerEvent("action", { key });
    },

    handleMenuTap(this: GuidePopupInstance, e: WechatMiniprogram.CustomEvent) {
      const key = (e.currentTarget.dataset as { key?: string }).key || "";
      if (!key) return;

      this.triggerEvent("action", { key });
    },
  },
});
