import type { Draft, EffectDraft } from "./ItemStudioTypes";

// ===== Build effects payload from draft =====

export function buildEffectsPayload(effects: EffectDraft[]) {
  return effects
    .map((eff) => {
      switch (eff.kind) {
        case "ADD_XP":
          return { type: "ADD_XP", amount: Number(eff.amount || 0) };
        case "ADD_BALANCE":
          return { type: "ADD_BALANCE", amount: Number(eff.amount || 0) };
        case "REPLY_MESSAGE":
          return { type: "REPLY_MESSAGE", message: eff.message };
        case "XP_BOOST":
          return {
            type: "XP_BOOST",
            multiplier: Number(eff.multiplier || 1),
            ...(eff.durationSeconds
              ? { durationSeconds: Number(eff.durationSeconds) }
              : {}),
          };
        case "TEMP_ROLE":
          return {
            type: "TEMP_ROLE",
            roleId: eff.roleId,
            ...(eff.durationSeconds
              ? { durationSeconds: Number(eff.durationSeconds) }
              : {}),
          };
        case "COLOR_ROLE":
          return { type: "COLOR_ROLE", roleId: eff.roleId };
        case "LOOTBOX":
          return {
            type: "LOOTBOX",
            pool: eff.pool.map((entry) => {
              const loot: Record<string, unknown> = {
                type: entry.type,
                weight: Number(entry.weight || 1),
              };
              if (entry.type !== "NOTHING") {
                if (entry.amountMode === "range") {
                  loot.minAmount = Number(entry.minAmount || 0);
                  loot.maxAmount = Number(entry.maxAmount || 0);
                } else {
                  loot.amount = Number(entry.amount || 0);
                }
              }
              if (entry.type === "ITEM" && entry.itemId) {
                loot.itemId = Number(entry.itemId);
              }
              if (entry.message.trim()) {
                loot.message = entry.message.trim();
              }
              return loot;
            }),
          };
        default:
          return null;
      }
    })
    .filter(Boolean);
}

// ===== Build base payload from draft =====

export function buildBasePayload(draft: Draft) {
  const effects = buildEffectsPayload(draft.effects);
  return {
    name: draft.name.trim(),
    description: draft.description.trim() || null,
    type: draft.type,
    rarity: draft.rarity,
    price:
      draft.price && Number(draft.price) > 0 ? Number(draft.price) : null,
    usageData:
      draft.effects.length > 0
        ? { consume: draft.consume, effects }
        : null,
  } as Record<string, unknown>;
}

// ===== Submit: Edit existing item =====

export async function submitEditItem({
  editItemId,
  basePayload,
  imageMode,
  iconUrlInput,
  imageUrlInput,
  imageFile,
}: {
  editItemId: number;
  basePayload: Record<string, unknown>;
  imageMode: "upload" | "url";
  iconUrlInput: string;
  imageUrlInput: string;
  imageFile: File | null;
}) {
  const editPayload = { ...basePayload };
  if (imageMode === "url") {
    editPayload.iconUrl = iconUrlInput.trim();
    editPayload.imageUrl = imageUrlInput.trim();
  }

  const putRes = await fetch(`/api/items/${editItemId}`, {
    method: "PUT",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(editPayload),
    credentials: "same-origin",
  });

  if (!putRes.ok) {
    const body = (await putRes
      .json()
      .catch(() => ({ error: putRes.statusText }))) as { error?: string };
    throw new Error(body.error || "Failed to save item");
  }

  if (imageMode === "upload" && imageFile) {
    const form = new FormData();
    form.append("image", imageFile);
    const iconRes = await fetch(`/api/items/${editItemId}/icon`, {
      method: "POST",
      body: form,
      credentials: "same-origin",
    });
    if (!iconRes.ok) {
      const body = (await iconRes
        .json()
        .catch(() => ({ error: iconRes.statusText }))) as {
        error?: string;
      };
      throw new Error(body.error || "Failed to upload image");
    }
  }
}

// ===== Submit: Create new item =====

export async function submitCreateItem({
  basePayload,
  imageMode,
  iconUrlInput,
  imageUrlInput,
  imageFile,
}: {
  basePayload: Record<string, unknown>;
  imageMode: "upload" | "url";
  iconUrlInput: string;
  imageUrlInput: string;
  imageFile: File | null;
}) {
  const payload = {
    ...basePayload,
    iconUrl: imageMode === "url" ? iconUrlInput.trim() : "",
    imageUrl: imageMode === "url" ? imageUrlInput.trim() : "",
  };

  let res: Response;
  if (imageMode === "upload" && imageFile) {
    const form = new FormData();
    form.append("data", JSON.stringify(payload));
    form.append("image", imageFile);
    res = await fetch("/api/items", {
      method: "POST",
      body: form,
      credentials: "same-origin",
    });
  } else {
    res = await fetch("/api/items", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(payload),
      credentials: "same-origin",
    });
  }

  if (!res.ok) {
    const body = (await res
      .json()
      .catch(() => ({ error: res.statusText }))) as { error?: string };
    throw new Error(body.error || "Failed to create item");
  }
}
