import { reactive } from "vue";
import request from "~/utils/request";
import { CurrentOrgId, HtyAuthToken, HtySudoToken } from "~/utils";
import type { Organization } from "~/types";
import { showDialog, showFailToast } from "vant";

interface OrgState {
  currentOrgId?: string;
  orgs: Organization[];
  homepageMd?: string;
}

const store = reactive<OrgState>({
  currentOrgId: window.localStorage.getItem(CurrentOrgId) || undefined,
  orgs: [],
  homepageMd: "",
});

type JwtPayloadDebug = {
  token_id?: string;
  current_org_id?: string;
  current_org_role_keys?: string[];
};

type JwtDecodeResult = {
  payload?: JwtPayloadDebug;
  error?: string;
};

const extractOrgContextFromPayload = (payload: Record<string, unknown>): JwtPayloadDebug => {
  if (payload.current_org_id || payload.token_id || payload.current_org_role_keys) {
    return {
      token_id: payload.token_id as string | undefined,
      current_org_id: payload.current_org_id as string | undefined,
      current_org_role_keys: payload.current_org_role_keys as string[] | undefined,
    };
  }
  if (typeof payload.sub === "string" && payload.sub.length > 0) {
    try {
      const subjectPayload = JSON.parse(payload.sub) as Record<string, unknown>;
      return {
        token_id: subjectPayload.token_id as string | undefined,
        current_org_id: subjectPayload.current_org_id as string | undefined,
        current_org_role_keys: subjectPayload.current_org_role_keys as string[] | undefined,
      };
    } catch (_error) {
      return {};
    }
  }
  return {};
};

const decodeJwtPayload = (token: string): JwtDecodeResult => {
  try {
    const tokenParts = token.split(".");
    if (tokenParts.length < 2) {
      return { error: "invalid token parts" };
    }
    const payloadRaw = tokenParts[1].replace(/-/g, "+").replace(/_/g, "/");
    const payloadRawWithPadding = payloadRaw.padEnd(
      Math.ceil(payloadRaw.length / 4) * 4,
      "="
    );
    const binary = atob(payloadRawWithPadding);
    const bytes = Uint8Array.from(binary, (char) => char.charCodeAt(0));
    const payloadJson = new TextDecoder("utf-8").decode(bytes);
    const payload = JSON.parse(payloadJson) as Record<string, unknown>;
    const orgContext = extractOrgContextFromPayload(payload);
    return {
      payload: orgContext,
    };
  } catch (error) {
    return {
      error: error instanceof Error ? error.message : "decode jwt payload failed",
    };
  }
};

export default function useOrg() {
  const loadMyOrgs = async () => {
    const { r, d, e } = await request({
      url: "/api/v1/uc/org/my_orgs",
      method: "GET",
    });
    if (r) {
      store.orgs = d || [];
      return store.orgs;
    }
    store.orgs = [];
    showFailToast(e);
    return [];
  };

  const switchOrg = async (orgId: string) => {
    const beforeAuthToken = window.localStorage.getItem(HtyAuthToken) || "";
    const beforeDecodeResult = beforeAuthToken
      ? decodeJwtPayload(beforeAuthToken)
      : { error: "missing auth token before switch" };
    const { r, d, e } = await request({
      url: "/api/v1/uc/org/switch",
      method: "POST",
      data: { org_id: orgId },
    });
    if (!r) {
      showFailToast(e);
      return false;
    }
    if (typeof d !== "string") {
      showFailToast("机构切换失败：返回 token 非法");
      return false;
    }
    const afterDecodeResult = decodeJwtPayload(d);
    const tokenOrgId = afterDecodeResult.payload?.current_org_id;
    const debugPayload = {
      switch_target_org_id: orgId,
      before: beforeDecodeResult,
      after: afterDecodeResult,
      response_error: e,
      response_ok: r,
      returned_token_length: d.length,
      role_keys_count: afterDecodeResult.payload?.current_org_role_keys?.length || 0,
      timestamp: new Date().toISOString(),
    };
    window.localStorage.setItem("OrgSwitchDebug", JSON.stringify(debugPayload));
    console.warn("[OrgSwitchDebug]", debugPayload);

    if (!tokenOrgId) {
      showDialog({
        title: "机构切换调试信息",
        message: "token 缺少机构上下文，请打开 vConsole 查看 [OrgSwitchDebug]",
      });
      return false;
    }
    window.localStorage.setItem(HtyAuthToken, d);
    window.localStorage.setItem(HtySudoToken, d);
    window.localStorage.setItem(CurrentOrgId, tokenOrgId);
    store.currentOrgId = tokenOrgId;
    return true;
  };

  const getHomepage = async (orgId: string) => {
    const { r, d, e } = await request({
      url: `/api/v1/uc/org/homepage/${orgId}`,
      method: "GET",
    });
    if (r) {
      store.homepageMd = d || "";
      return store.homepageMd;
    }
    showFailToast(e);
    return "";
  };

  const saveHomepage = async (orgId: string, markdownText: string) => {
    const { r, d, e } = await request({
      url: "/api/v1/uc/org/save_homepage",
      method: "POST",
      data: {
        id: orgId,
        homepage_md: markdownText,
      },
    });
    if (r) {
      store.homepageMd = d?.homepage_md || markdownText;
      return true;
    }
    showFailToast(e);
    return false;
  };

  return {
    store,
    loadMyOrgs,
    switchOrg,
    getHomepage,
    saveHomepage,
  };
}
