export type SupportedModel = string;
export type AgentModelIcon = "bolt" | "sparkle";

export type AgentModelOption = {
  id: SupportedModel;
  label: string;
  description: string;
  icon: AgentModelIcon;
};

export const defaultAgentModelOptions: AgentModelOption[] = [
  {
    id: "deepseek/deepseek-v4-flash",
    label: "快速",
    description: "快速回答和任务执行",
    icon: "bolt",
  },
  {
    id: "deepseek/deepseek-v4-pro",
    label: "专家",
    description: "探索、解决复杂任务",
    icon: "sparkle",
  },
];

export const defaultAgentModelOptionsJson = JSON.stringify(defaultAgentModelOptions);

const isObjectRecord = (value: unknown): value is Record<string, unknown> =>
  typeof value === "object" && value !== null && !Array.isArray(value);

export const parseAgentModelOptions = (value: string): AgentModelOption[] => {
  let parsed: unknown;
  try {
    parsed = JSON.parse(value);
  } catch {
    throw new Error("OPENCODE_MODEL_OPTIONS must be valid JSON");
  }
  if (!Array.isArray(parsed)) {
    throw new Error("OPENCODE_MODEL_OPTIONS must be a JSON array");
  }

  const seen = new Set<string>();
  return parsed.map((item, index) => {
    if (!isObjectRecord(item)) {
      throw new Error(`OPENCODE_MODEL_OPTIONS[${index}] must be an object`);
    }
    const id = typeof item.id === "string" ? item.id.trim() : "";
    if (!id) {
      throw new Error(`OPENCODE_MODEL_OPTIONS[${index}].id is required`);
    }
    if (seen.has(id)) {
      throw new Error(`duplicate OPENCODE_MODEL_OPTIONS id: ${id}`);
    }
    seen.add(id);

    const label =
      typeof item.label === "string" && item.label.trim()
        ? item.label.trim()
        : id;
    const description =
      typeof item.description === "string" && item.description.trim()
        ? item.description.trim()
        : label;
    const icon = item.icon === "bolt" || item.icon === "sparkle"
      ? item.icon
      : "sparkle";

    return {
      id,
      label,
      description,
      icon,
    };
  });
};

export const getAgentModelIds = (options: AgentModelOption[]) =>
  options.map((option) => option.id);
