import { sdk } from "@/lib/auth";
import { REGION_ID } from "@/lib/medusa";

export const CART_ID_KEY = "ot_medusa_cart_id";
export const CART_SNAPSHOT_KEY = "ot_medusa_cart_snapshot";

export type CartItem = {
  id: string;
  productId: string;
  variantId: string;
  slug: string;
  name: string;
  price: number;
  image: string;
  size: string;
  color: string;
  /** Tipo de falda (solo set polo & falda) */
  skirt?: string;
  qty: number;
};

export const CART_FIELDS =
  "*items,*items.product,*items.variant,*items.variant.options,*items.variant.options.option,+items.metadata";

type LineItem = {
  id?: string;
  title?: string;
  thumbnail?: string | null;
  quantity?: number;
  unit_price?: number;
  product_id?: string;
  variant_id?: string;
  metadata?: Record<string, unknown> | null;
  product?: { handle?: string; title?: string };
  variant?: {
    title?: string;
    options?: { value?: string; option?: { title?: string } }[];
  };
};

type StoreCart = {
  id: string;
  item_subtotal?: number;
  subtotal?: number;
  completed_at?: string | null;
  items?: LineItem[];
};

function sizeColorFromVariant(item: LineItem) {
  const fromOptions: Record<string, string> = {};
  for (const opt of item.variant?.options || []) {
    const title = opt.option?.title?.toLowerCase() || "";
    if (title && opt.value) fromOptions[title] = opt.value;
  }
  const parts = (item.variant?.title || "").split(" / ").map((p) => p.trim());
  if (fromOptions["talla dama"] && fromOptions["talla caballero"]) {
    return {
      size: `Dama ${fromOptions["talla dama"]} · Caballero ${fromOptions["talla caballero"]}`,
      color: fromOptions.color || parts[parts.length - 1] || "Único",
    };
  }
  return {
    size: fromOptions.talla || parts[0] || "U",
    color: fromOptions.color || parts[1] || "Único",
  };
}

export function mapCartItems(cart: StoreCart | null | undefined): CartItem[] {
  return (cart?.items || [])
    .filter((item) => item.id)
    .map((item) => {
      const { size, color } = sizeColorFromVariant(item);
      const skirtRaw =
        item.metadata?.skirt_label ||
        item.metadata?.skirt_type ||
        item.metadata?.skirt;
      const skirt = typeof skirtRaw === "string" ? skirtRaw : undefined;
      return {
        id: item.id as string,
        productId: item.product_id || "",
        variantId: item.variant_id || "",
        slug: item.product?.handle || "",
        name: item.product?.title || item.title || "Prenda",
        price: item.unit_price || 0,
        image: item.thumbnail || "/brand/senora-clasica.jpg",
        size,
        color,
        skirt,
        qty: item.quantity || 1,
      };
    });
}

export function cartSubtotal(cart: StoreCart | null | undefined, items: CartItem[]) {
  if (typeof cart?.item_subtotal === "number") return cart.item_subtotal;
  if (typeof cart?.subtotal === "number") return cart.subtotal;
  return items.reduce((n, i) => n + i.price * i.qty, 0);
}

export function saveCartSnapshot(cartId: string, items: CartItem[], subtotal: number) {
  if (typeof window === "undefined") return;
  window.localStorage.setItem(CART_ID_KEY, cartId);
  window.localStorage.setItem(
    CART_SNAPSHOT_KEY,
    JSON.stringify({ cartId, items, subtotal, savedAt: Date.now() })
  );
}

export function readCartSnapshot(): {
  cartId: string;
  items: CartItem[];
  subtotal: number;
} | null {
  if (typeof window === "undefined") return null;
  try {
    const raw = window.localStorage.getItem(CART_SNAPSHOT_KEY);
    if (!raw) return null;
    const parsed = JSON.parse(raw) as {
      cartId?: string;
      items?: CartItem[];
      subtotal?: number;
    };
    if (!parsed.cartId || !Array.isArray(parsed.items)) return null;
    return {
      cartId: parsed.cartId,
      items: parsed.items,
      subtotal: parsed.subtotal || 0,
    };
  } catch {
    return null;
  }
}

export function clearCartSnapshot() {
  if (typeof window === "undefined") return;
  window.localStorage.removeItem(CART_SNAPSHOT_KEY);
}

export function isMissingCartError(error: unknown) {
  const message = error instanceof Error ? error.message : String(error || "");
  const text = message.toLowerCase();
  return (
    text.includes("not found") ||
    text.includes("404") ||
    text.includes("already completed") ||
    (text.includes("cart") && text.includes("completed"))
  );
}

/** Mensajes claros cuando Medusa/Apache responde 503 u otros fallos de red. */
export function friendlyCartError(error: unknown, fallback: string) {
  const message = error instanceof Error ? error.message : String(error || "");
  const text = message.toLowerCase();
  if (
    text.includes("service unavailable") ||
    text.includes("503") ||
    text.includes("econnrefused") ||
    text.includes("failed to fetch") ||
    text.includes("network")
  ) {
    return "La tienda se estaba reiniciando. Espera unos segundos e intenta de nuevo.";
  }
  return message || fallback;
}

/** Alias: carrito completado o inexistente → hay que crear uno nuevo. */
export function isUnusableCartError(error: unknown) {
  return isMissingCartError(error);
}

export async function retrieveCart(cartId: string) {
  const { cart } = await sdk.store.cart.retrieve(cartId, { fields: CART_FIELDS });
  const storeCart = cart as StoreCart;
  if (storeCart.completed_at) {
    throw new Error(`Cart ${cartId} is already completed.`);
  }
  return storeCart;
}

export async function createCart() {
  const { cart } = await sdk.store.cart.create(
    { region_id: REGION_ID },
    { fields: CART_FIELDS }
  );
  return cart as StoreCart;
}

export async function addLineItem(
  cartId: string,
  variantId: string,
  quantity: number,
  metadata?: Record<string, string>
) {
  const { cart } = await sdk.store.cart.createLineItem(
    cartId,
    {
      variant_id: variantId,
      quantity,
      ...(metadata && Object.keys(metadata).length ? { metadata } : {}),
    },
    { fields: CART_FIELDS }
  );
  return cart as StoreCart;
}

export async function updateLineItem(cartId: string, lineItemId: string, quantity: number) {
  const { cart } = await sdk.store.cart.updateLineItem(
    cartId,
    lineItemId,
    { quantity },
    { fields: CART_FIELDS }
  );
  return cart as StoreCart;
}

export async function deleteLineItem(cartId: string, lineItemId: string) {
  await sdk.store.cart.deleteLineItem(cartId, lineItemId);
  // Siempre reconsultar: el `parent` del delete a veces viene sin *items expandido.
  return retrieveCart(cartId);
}

export async function transferCartToCustomer(cartId: string) {
  const { cart } = await sdk.store.cart.transferCart(cartId, {
    fields: CART_FIELDS,
  });
  return cart as StoreCart;
}

export type ShippingInput = {
  email: string;
  firstName: string;
  lastName: string;
  phone: string;
  address: string;
  address2?: string;
  city: string;
  province: string;
  postalCode?: string;
  notes?: string;
};

export async function updateCartShipping(cartId: string, input: ShippingInput) {
  const address = {
    first_name: input.firstName,
    last_name: input.lastName,
    phone: input.phone,
    address_1: input.address,
    address_2: input.address2 || "",
    city: input.city,
    province: input.province,
    postal_code: input.postalCode || "000000",
    country_code: "co",
  };
  const { cart } = await sdk.store.cart.update(
    cartId,
    {
      email: input.email,
      shipping_address: address,
      billing_address: address,
      metadata: {
        delivery_notes: input.notes || "",
        shipping_city: input.city,
        shipping_province: input.province,
      },
    },
    { fields: CART_FIELDS }
  );
  return cart as StoreCart;
}
