import { computed, onBeforeUnmount, onMounted, ref } from "vue";
import QRCode from "qrcode";
import { ElMessageBox } from "element-plus";

import { showError, showSuccess } from "@/lib/feedback";
import { formatAdminDateTime } from "@/utils/admin-time";
import {
  confirmKuaishouCloudClaimRole,
  fetchClaimDetail,
  redeemKuaishouCloudClaim,
  verifyKuaishouCloudClaimTicket,
} from "@/services/claim";
import type { ClaimDetailData } from "@/types/claim";

export function useKuaishouCloudClaim(token: () => string) {
  const loading = ref(true);
  const submitting = ref(false);
  const refreshingRole = ref(false);
  const confirmingRole = ref(false);
  const redeeming = ref(false);
  const errorMessage = ref("");
  const detail = ref<ClaimDetailData | null>(null);
  const ticketCode = ref("");
  const qrCodeDataUrl = ref("");
  let pollTimer = 0;

  // ── derived data ────────────────────────────────────────

  const flow = computed(() => detail.value?.kuaishouCloudFulfillment || null);
  const order = computed(() => detail.value?.order || null);
  const orderItem = computed(() => detail.value?.orderItem || null);
  const task = computed(() => detail.value?.task || null);

  // ── computed status flags ───────────────────────────────

  const roleName = computed(
    () => flow.value?.role.name || flow.value?.binding.roleName || ""
  );
  const roleId = computed(
    () => flow.value?.role.rid || flow.value?.binding.roleId || ""
  );
  const isTicketVerified = computed(
    () => flow.value?.ticket.status === "verified"
  );

  const isBindUrlExpired = computed(() => {
    const expiresAt = String(flow.value?.binding.bindExpiresAt || "").trim();
    if (!expiresAt) {
      return false;
    }
    const expiresTime = Date.parse(expiresAt);
    return Number.isFinite(expiresTime) && expiresTime <= Date.now();
  });

  const isBindingPrepared = computed(
    () =>
      flow.value?.binding.prepareStatus === "ready" &&
      Boolean(String(flow.value?.binding.bindUrl || "").trim()) &&
      !isBindUrlExpired.value
  );

  const isBindingPreparing = computed(
    () => flow.value?.binding.prepareStatus === "pending"
  );
  const canEnterBindingStep = computed(() => isTicketVerified.value);
  const isRoleReady = computed(() => Boolean(roleName.value || roleId.value));
  const isRoleConfirmed = computed(
    () => String(task.value?.status || "").trim() === "role_confirmed"
  );
  const isDispatched = computed(
    () => String(flow.value?.dispatch.status || "").trim() === "success"
  );

  const isCompleted = computed(
    () =>
      String(task.value?.status || "").trim() === "completed" ||
      String(flow.value?.consume.status || "").trim() === "success"
  );

  const hasRedeemResult = computed(() => {
    const status = String(task.value?.status || "").trim();
    return (
      isDispatched.value ||
      [
        "dispatched_pending_return",
        "completed",
        "manual_review",
        "failed",
      ].includes(status)
    );
  });

  const canSubmitTicket = computed(
    () =>
      !["completed", "manual_review", "closed", "expired"].includes(
        String(task.value?.status || "").trim()
      ) && !submitting.value
  );

  const currentStep = computed(() => {
    if (hasRedeemResult.value) {
      return 4;
    }
    if (isRoleConfirmed.value) {
      return 3;
    }
    if (canEnterBindingStep.value) {
      return 2;
    }
    return 1;
  });

  const progressText = computed(() => {
    if (hasRedeemResult.value) {
      return "兑换结果已生成";
    }
    if (isRoleConfirmed.value) {
      return "角色已确认，等待兑换";
    }
    if (isTicketVerified.value) {
      return isBindingPrepared.value
        ? "请完成扫码绑定"
        : "绑定链接刷新中，请稍候";
    }
    return "等待提交核销码";
  });

  const resultTitle = computed(() => {
    if (isCompleted.value) {
      return "兑换成功";
    }
    if (isDispatched.value) {
      return "兑换请求已提交";
    }
    return "结果已记录";
  });

  const resultDescription = computed(() => {
    if (isCompleted.value) {
      return "当前兑换流程已经完成。发货、退号和核销结果会保存在后台任务界面。";
    }
    return "你的兑换请求已经提交。发货、退号和核销结果会由系统保存在后台任务界面，无需在此页面等待。";
  });

  // ── actions ─────────────────────────────────────────────

  async function generateQRCode(url: string) {
    if (!url) {
      qrCodeDataUrl.value = "";
      return;
    }
    try {
      qrCodeDataUrl.value = await QRCode.toDataURL(url, {
        width: 280,
        margin: 2,
        color: {
          dark: "#0f172a",
          light: "#ffffff",
        },
      });
    } catch (error) {
      qrCodeDataUrl.value = "";
      console.error("生成二维码失败:", error);
    }
  }

  async function applyDetail(nextDetail: ClaimDetailData) {
    detail.value = nextDetail;
    if (!ticketCode.value && nextDetail.kuaishouCloudFulfillment?.ticket.code) {
      ticketCode.value = nextDetail.kuaishouCloudFulfillment.ticket.code;
    }
    await generateQRCode(
      String(nextDetail.kuaishouCloudFulfillment?.binding.bindUrl || "").trim()
    );
  }

  async function loadDetail(options: { silent?: boolean } = {}) {
    if (!options.silent) {
      loading.value = true;
    }
    errorMessage.value = "";
    try {
      const response = await fetchClaimDetail(token());
      await applyDetail(response.data);
      syncPolling();
    } catch (error) {
      errorMessage.value =
        error instanceof Error ? error.message : "读取领取信息失败";
      stopPolling();
    } finally {
      if (!options.silent) {
        loading.value = false;
      }
    }
  }

  async function submitTicket() {
    const normalizedTicketCode = ticketCode.value.trim();
    if (!normalizedTicketCode) {
      showError("请输入核销码");
      return;
    }

    submitting.value = true;
    try {
      const response = await verifyKuaishouCloudClaimTicket(token(), {
        ticketCode: normalizedTicketCode,
      });
      await applyDetail(response.data);
      showSuccess("核销码验证通过，系统已开始准备绑定资源");
      syncPolling();
    } catch (error) {
      showError(error instanceof Error ? error.message : "核销码验证失败");
    } finally {
      submitting.value = false;
    }
  }

  async function refreshRole() {
    refreshingRole.value = true;
    try {
      await loadDetail({ silent: true });
      if (isRoleReady.value) {
        showSuccess("角色信息已刷新");
      } else {
        showError(
          flow.value?.role.errorMessage ||
            "暂时还没有识别到角色信息，请完成绑定后稍等片刻再试"
        );
      }
    } finally {
      refreshingRole.value = false;
    }
  }

  async function confirmRole() {
    confirmingRole.value = true;
    try {
      const response = await confirmKuaishouCloudClaimRole(token());
      await applyDetail(response.data);
      showSuccess("角色已确认，进入下一步");
      syncPolling();
    } catch (error) {
      showError(error instanceof Error ? error.message : "确认角色失败");
    } finally {
      confirmingRole.value = false;
    }
  }

  async function confirmRedeem() {
    try {
      await ElMessageBox.confirm(
        "兑换后不可取消，也不可退货。请确认角色和商品信息完全正确。",
        "确认兑换",
        {
          confirmButtonText: "确认兑换",
          cancelButtonText: "取消",
          type: "warning",
          center: true,
        }
      );
    } catch {
      return;
    }

    redeeming.value = true;
    try {
      const response = await redeemKuaishouCloudClaim(token());
      await applyDetail(response.data);
      showSuccess("兑换请求已提交");
      syncPolling();
    } catch (error) {
      showError(error instanceof Error ? error.message : "兑换失败");
    } finally {
      redeeming.value = false;
    }
  }

  function openBindUrl(useCurrentPage = false) {
    const bindUrl = String(flow.value?.binding.bindUrl || "").trim();
    if (!bindUrl) {
      showError("绑定链接还没准备好，请稍后刷新");
      return;
    }
    if (useCurrentPage) {
      window.location.assign(bindUrl);
      return;
    }
    window.open(bindUrl, "_blank", "noopener,noreferrer");
  }

  // ── polling ─────────────────────────────────────────────

  function stopPolling() {
    if (pollTimer) {
      window.clearInterval(pollTimer);
      pollTimer = 0;
    }
  }

  function syncPolling() {
    const taskStatus = String(task.value?.status || "").trim();
    const shouldPoll =
      Boolean(flow.value) &&
      !hasRedeemResult.value &&
      !["closed", "expired"].includes(taskStatus);

    if (!shouldPoll) {
      stopPolling();
      return;
    }
    if (pollTimer) {
      return;
    }
    pollTimer = window.setInterval(() => {
      void loadDetail({ silent: true });
    }, 4000);
  }

  // ── lifecycle ───────────────────────────────────────────

  onMounted(() => {
    void loadDetail();
  });

  onBeforeUnmount(() => {
    stopPolling();
  });

  return {
    // state
    loading,
    submitting,
    refreshingRole,
    confirmingRole,
    redeeming,
    errorMessage,
    detail,
    ticketCode,
    qrCodeDataUrl,
    // derived data
    flow,
    order,
    orderItem,
    task,
    // computed status
    roleName,
    roleId,
    isTicketVerified,
    isBindUrlExpired,
    isBindingPrepared,
    isBindingPreparing,
    canEnterBindingStep,
    isRoleReady,
    isRoleConfirmed,
    isDispatched,
    isCompleted,
    hasRedeemResult,
    canSubmitTicket,
    currentStep,
    progressText,
    resultTitle,
    resultDescription,
    // actions
    loadDetail,
    submitTicket,
    refreshRole,
    confirmRole,
    confirmRedeem,
    openBindUrl,
    // utility
    formatAdminDateTime,
  };
}
