import {
  useMutation,
  useQuery,
  useQueryClient,
} from "@tanstack/react-query";
import { apiRequest } from "../lib/api-client";
import { useAuthStore } from "../stores/auth.store";
import { monthDateRange } from "../utils/date";
import type {
  CreateTransactionInput,
  TransactionFilters,
} from "@haushaltsApp/shared/schemas/transaction";

export type TransactionWithCategory = {
  id: string;
  amount: string;
  type: "income" | "expense";
  scope: "household" | "private" | "child";
  childId: string | null;
  isFixed: boolean;
  isCarryOver: boolean;
  description: string | null;
  merchant: string | null;
  date: string;
  categoryName: string | null;
  categoryIcon: string | null;
  categoryColor: string | null;
  createdAt: string;
};

export type TransactionSummary = {
  income: number;
  expense: number;
  balance: number;
};

export function useTransactions(filters?: Partial<TransactionFilters>) {
  const activeHouseholdId = useAuthStore((s) => s.activeHouseholdId);
  const params = new URLSearchParams();
  if (filters?.type) params.set("type", filters.type);
  if (filters?.categoryId) params.set("categoryId", filters.categoryId);
  if (filters?.scope) params.set("scope", filters.scope);
  if (filters?.childId) params.set("childId", filters.childId);
  if (filters?.from) params.set("from", filters.from);
  if (filters?.to) params.set("to", filters.to);
  const query = params.toString();

  return useQuery({
    queryKey: ["transactions", activeHouseholdId, filters],
    queryFn: () =>
      apiRequest<{ transactions: TransactionWithCategory[] }>(
        `/api/transactions${query ? `?${query}` : ""}`,
      ),
    select: (data) => data.transactions,
    enabled: !!activeHouseholdId,
  });
}

export function useTransactionSummary(scope?: "household" | "private" | "child") {
  const activeHouseholdId = useAuthStore((s) => s.activeHouseholdId);
  const query = scope ? `?scope=${scope}` : "";
  return useQuery({
    queryKey: ["transactions", "summary", activeHouseholdId, scope],
    queryFn: () => apiRequest<TransactionSummary>(`/api/transactions/summary${query}`),
    enabled: !!activeHouseholdId,
  });
}

export function useCreateTransaction() {
  const queryClient = useQueryClient();
  return useMutation({
    mutationFn: (input: CreateTransactionInput) =>
      apiRequest<{ transaction: TransactionWithCategory }>("/api/transactions", {
        method: "POST",
        body: JSON.stringify(input),
      }),
    onSuccess: () => {
      void queryClient.invalidateQueries({ queryKey: ["transactions"] });
    },
  });
}

export function useDeleteTransaction() {
  const queryClient = useQueryClient();
  return useMutation({
    mutationFn: (id: string) =>
      apiRequest(`/api/transactions/${id}`, { method: "DELETE" }),
    onSuccess: () => {
      void queryClient.invalidateQueries({ queryKey: ["transactions"] });
    },
  });
}

export function useUpdateTransaction() {
  const queryClient = useQueryClient();
  return useMutation({
    mutationFn: ({ id, ...input }: { id: string } & Partial<CreateTransactionInput>) =>
      apiRequest<{ transaction: TransactionWithCategory }>(`/api/transactions/${id}`, {
        method: "PATCH",
        body: JSON.stringify(input),
      }),
    onSuccess: () => {
      void queryClient.invalidateQueries({ queryKey: ["transactions"] });
    },
  });
}

export function useActivateFixed() {
  const queryClient = useQueryClient();
  return useMutation({
    mutationFn: (params: {
      month: string;
      scope: "household" | "private" | "child";
      childId?: string;
    }) =>
      apiRequest<{ created: number }>("/api/transactions/activate-fixed", {
        method: "POST",
        body: JSON.stringify(params),
      }),
    onSuccess: (data) => {
      if (data.created > 0) {
        void queryClient.invalidateQueries({ queryKey: ["transactions"] });
      }
    },
  });
}

export function useCarryOver() {
  const queryClient = useQueryClient();
  return useMutation({
    mutationFn: (params: {
      fromMonth: string;
      toMonth: string;
      scope: "household" | "private" | "child";
      childId?: string;
    }) =>
      apiRequest<{ transaction: TransactionWithCategory }>("/api/transactions/carry-over", {
        method: "POST",
        body: JSON.stringify(params),
      }),
    onSuccess: () => {
      void queryClient.invalidateQueries({ queryKey: ["transactions"] });
    },
  });
}

export function useMonthBalance(
  scope: "household" | "private" | "child",
  month: string,
  childId?: string,
) {
  const activeHouseholdId = useAuthStore((s) => s.activeHouseholdId);
  const [from, to] = monthDateRange(month);

  const params = new URLSearchParams({ scope, from, to });
  if (childId) params.set("childId", childId);

  return useQuery({
    queryKey: ["transactions", "balance", activeHouseholdId, scope, month, childId],
    queryFn: () =>
      apiRequest<{ transactions: TransactionWithCategory[] }>(
        `/api/transactions?${params.toString()}`,
      ).then((data) => {
        let income = 0;
        let expense = 0;
        for (const tx of data.transactions) {
          if (tx.type === "income") income += parseFloat(tx.amount);
          else expense += parseFloat(tx.amount);
        }
        return { income, expense, balance: income - expense };
      }),
    enabled: !!activeHouseholdId,
  });
}
