'use client';

import { useMutation, useQueryClient } from '@tanstack/react-query';
import { getCsrfToken } from '@/lib/csrf';
import { clearLocalCart, readLocalCart } from './anonCartStore';
import type { CartItem } from './useCart';

export interface MergeResult {
  merged: CartItem[];
  removed: { dealId: string; reason: string }[];
}
interface ServerMergeItem {
  dealSkuId?: string | null;
  dealId?: string;
  qty: number;
  addedAt: string | Date;
  dealTitle?: string;
  vendorName?: string;
  discountedPrice?: string | number;
  maxPerUser?: number | null;
  remainingStock?: number;
  imageUrl?: string | null;
}
interface ServerMergeResponse {
  ok: boolean;
  items?: ServerMergeItem[];
  removed?: { dealId: string; reason: string }[];
  error?: string;
}
const agorot = (value: string | number | undefined) =>
  value === undefined
    ? undefined
    : typeof value === 'number'
      ? Math.round(value)
      : Number.isFinite(parseFloat(value))
        ? Math.round(parseFloat(value) * 100)
        : undefined;
const normalize = (item: ServerMergeItem): CartItem => ({
  dealSkuId: item.dealSkuId ?? item.dealId ?? '',
  dealId: item.dealId,
  qty: item.qty,
  addedAt: item.addedAt instanceof Date ? item.addedAt.toISOString() : item.addedAt,
  title: item.dealTitle,
  vendorName: item.vendorName,
  unitPrice: agorot(item.discountedPrice),
  maxQty:
    item.maxPerUser !== undefined && item.remainingStock !== undefined
      ? item.maxPerUser === null
        ? item.remainingStock
        : Math.min(item.maxPerUser, item.remainingStock)
      : undefined,
  imageId: item.imageUrl ?? undefined,
});

async function postMerge(items: { dealSkuId: string; qty: number }[]): Promise<MergeResult> {
  const response = await fetch('/api/cart/merge', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json', 'x-csrf-token': getCsrfToken() },
    body: JSON.stringify({ items }),
  });
  const data = (await response.json()) as ServerMergeResponse;
  if (!data.ok) throw new Error(data.error ?? 'Merge failed');
  return { merged: (data.items ?? []).map(normalize), removed: data.removed ?? [] };
}

export function useCartMerge() {
  const queryClient = useQueryClient();
  const mutation = useMutation({
    mutationFn: async (): Promise<MergeResult> => {
      const localItems = readLocalCart();
      if (localItems.length === 0) return { merged: [], removed: [] };
      const result = await postMerge(localItems.map(({ dealSkuId, qty }) => ({ dealSkuId, qty })));
      clearLocalCart();
      queryClient.setQueryData(['cart'], {
        items: result.merged,
        subtotal: result.merged.reduce((sum, item) => sum + (item.unitPrice ?? 0) * item.qty, 0),
      });
      return result;
    },
    onSettled: () => {
      void queryClient.invalidateQueries({ queryKey: ['cart'] });
    },
  });
  return {
    mergeFromLocalStorage: () => mutation.mutateAsync(),
    isPending: mutation.isPending,
    isError: mutation.isError,
  };
}
