import { computed, ref, watch } from "vue";
import { defineStore } from "pinia";
import { modelManagementApi } from "../service/api/modelManagement.js";

const STORAGE_KEY = "bimAdmin.modelCenter.v1";
const DEFAULT_MODEL_URL = "https://lyz-1259524260.cos.ap-guangzhou.myqcloud.com/iflow/models/417664a3-76c8-4d94-9344-1337246a5d4e";

function createSeedModel() {
  const url = String(import.meta.env.VITE_BIM_MODEL_URL || DEFAULT_MODEL_URL).trim();
  return {
    id: "model-seed",
    name: "XXX特大桥主体模型.rvt",
    type: "bridge",
    url,
    fileName: "XXX特大桥主体模型.rvt",
    fileSize: 0,
    uploadedAt: "2026-06-09 09:00",
  };
}

function formatTimestamp(date = new Date()) {
  const pad = (value) => String(value).padStart(2, "0");
  return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} ${pad(date.getHours())}:${pad(date.getMinutes())}`;
}

function safeParse(raw) {
  try {
    return JSON.parse(raw);
  } catch {
    return null;
  }
}

function resolveModelUrl(item) {
  const codeData = typeof item?.codeData === "string" ? safeParse(item.codeData) : item?.codeData;
  const isBackendModel = item?.isBackendModel === true || item?.modelId != null || item?.ossId != null || item?.codeData != null;
  if (isBackendModel) {
    if (String(item?.convertStatus ?? item?.convert_status ?? "").trim() !== "SUCCESS") return "";
    return String(codeData?.convertedUrl ?? codeData?.converted_url ?? item?.convertedUrl ?? item?.converted_url ?? "").trim();
  }
  return String(
    item?.url ??
    item?.fileUrl ??
    "",
  ).trim();
}

function normalizeModelType(type) {
  const text = String(type || "");
  return ({
    bridge: "bridge",
    building: "building",
    structure: "structure",
    mechanical: "mechanical",
    桥梁主体: "bridge",
    建筑主体: "building",
    结构模型: "structure",
    机电模型: "mechanical",
  })[text] || text || "bridge";
}

function normalizeModel(item, index) {
  if (!item || typeof item !== "object") return null;
  const id = String(item.id ?? item.modelId ?? `model-${index + 1}`);
  const name = String(item.name ?? item.modelName ?? item.originalName ?? item.fileName ?? "未命名模型");
  const fileName = String(item.originalName ?? item.fileName ?? name);
  const url = resolveModelUrl(item);
  const isBackendModel = item.isBackendModel === true || item.modelId != null || item.ossId != null || item.codeData != null;
  return {
    id,
    name,
    type: normalizeModelType(item.type ?? item.modelType),
    url,
    isBackendModel,
    fileName,
    fileSize: Number(item.fileSize || 0),
    uploadedAt: String(item.uploadedAt ?? item.createTime ?? formatTimestamp()).replace("T", " ").slice(0, 16),
    status: String(item.status ?? "1"),
    convertStatus: String(item.convertStatus ?? item.convert_status ?? ""),
  };
}

function loadState() {
  const seed = createSeedModel();
  const raw = localStorage.getItem(STORAGE_KEY);
  const parsed = raw ? safeParse(raw) : null;
  const models = Array.isArray(parsed?.models)
    ? parsed.models.map(normalizeModel).filter(Boolean)
    : [seed];

  if (!models.length) models.push(seed);

  const activeId = models.some((item) => item.id === parsed?.activeId)
    ? String(parsed.activeId)
    : models[0].id;

  return { models, activeId };
}

export const useModelCenterStore = defineStore("modelCenter", () => {
  const loaded = loadState();
  const models = ref(loaded.models);
  const activeId = ref(loaded.activeId);

  const activeModel = computed(() => models.value.find((item) => item.id === activeId.value) || models.value[0] || null);
  const activeModelName = computed(() => activeModel.value?.name || "未选择模型");
  const activeModelUrl = computed(() => activeModel.value?.url || "");

  function persist() {
    const payload = {
      activeId: activeId.value,
      models: models.value.map((item) => ({
        id: item.id,
        name: item.name,
        type: item.type,
        url: item.url,
        isBackendModel: item.isBackendModel,
        convertedUrl: item.convertedUrl,
        fileName: item.fileName,
        fileSize: item.fileSize,
        uploadedAt: item.uploadedAt,
        status: item.status,
        convertStatus: item.convertStatus,
      })),
    };
    localStorage.setItem(STORAGE_KEY, JSON.stringify(payload));
  }

  function applyModels(list, preferredActiveId = activeId.value) {
    const nextModels = Array.isArray(list)
      ? list.map(normalizeModel).filter(Boolean)
      : [];
    if (!nextModels.length) {
      models.value = [];
      activeId.value = "";
      return;
    }
    models.value = nextModels;
    const preferredId = String(preferredActiveId || "");
    activeId.value = nextModels.some((item) => item.id === preferredId)
      ? preferredId
      : nextModels.find((item) => item.status === "0")?.id || nextModels[0].id;
  }

  async function loadModels(options = {}) {
    const list = await modelManagementApi.list();
    applyModels(list, options.preferredActiveId ?? activeId.value);
    return models.value;
  }

  async function addModel(payload) {
    const uploaded = await modelManagementApi.upload({
      file: payload.file,
      modelName: payload.name,
      modelType: payload.type,
    });
    const model = normalizeModel(uploaded, models.value.length);
    if (model?.id) {
      activeId.value = model.id;
      await modelManagementApi.switchCurrent(model.id);
      await loadModels({ preferredActiveId: model.id });
    }
    return model;
  }

  async function setActiveModel(id) {
    if (!models.value.some((item) => item.id === id)) return;
    await modelManagementApi.switchCurrent(id);
    activeId.value = id;
    models.value = models.value.map((item) => ({ ...item, status: item.id === id ? "0" : "1" }));
  }

  async function updateModel(id, payload) {
    const updated = await modelManagementApi.update(id, {
      modelName: payload.name,
      modelType: payload.type,
    });
    const normalized = normalizeModel(updated, models.value.findIndex((item) => item.id === id));
    models.value = models.value.map((item) => (
      item.id === id
        ? { ...item, ...(normalized || {}), id, name: payload.name, type: payload.type }
        : item
    ));
    await loadModels();
  }

  async function removeModel(id) {
    const index = models.value.findIndex((item) => item.id === id);
    if (index < 0) return;
    const removingActive = activeId.value === id;
    await modelManagementApi.remove(id);
    models.value.splice(index, 1);
    if (removingActive) {
      const nextId = models.value[0]?.id || "";
      if (nextId) await setActiveModel(nextId);
      else activeId.value = "";
    }
  }

  watch([models, activeId], persist, { deep: true });

  return {
    models,
    activeId,
    activeModel,
    activeModelName,
    activeModelUrl,
    loadModels,
    addModel,
    setActiveModel,
    updateModel,
    removeModel,
  };
});
