import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { api } from '@/lib/api';
import { requireSelectedStore, useSelectedStoreId } from '@/lib/stores/store-context';
import type {
  AdminResolveReturnInput,
  AdminReturnsListInput,
  CreateReturnInput,
  ProactiveRefundInput,
  ReturnAdminAction,
  ReturnState,
} from '@alqove/api-client';

export const RETURN_KEYS = {
  one: (returnId: string) => ['returns', returnId] as const,
  myList: (state?: ReturnState) => ['returns', 'me', state ?? 'all'] as const,
  sellerList: (storeId: string | null, state?: ReturnState) => ['returns', 'seller', storeId, state ?? 'all'] as const,
};

export const ADMIN_RETURN_KEYS = {
  list: (params: AdminReturnsListInput = {}) =>
    [
      'admin',
      'returns',
      params.state ?? 'all',
      params.include_resolved ? 'with_resolved' : 'open',
      params.page ?? 1,
      params.per_page ?? 20,
    ] as const,
};

export function useReturn(returnId: string | null, storeId?: string | null) {
  return useQuery({
    queryKey: storeId !== undefined ? ['returns', 'store', storeId, returnId] : returnId ? RETURN_KEYS.one(returnId) : ['returns', 'none'],
    queryFn: () => storeId !== undefined ? api.returns.forStore(requireSelectedStore(storeId)).get(returnId!) : api.returns.get(returnId!),
    enabled: Boolean(returnId) && storeId !== null,
    staleTime: 15_000,
  });
}

export function useMyReturns(params: { state?: ReturnState } = {}) {
  return useQuery({
    queryKey: RETURN_KEYS.myList(params.state),
    queryFn: () => api.returns.listMine(params),
    staleTime: 15_000,
  });
}

export function useSellerReturns(params: { state?: ReturnState } = {}) {
  const storeId = useSelectedStoreId();
  return useQuery({
    queryKey: RETURN_KEYS.sellerList(storeId, params.state),
    enabled: !!storeId,
    queryFn: () => api.returns.forStore(requireSelectedStore(storeId)).listSeller(params),
    staleTime: 15_000,
  });
}

function invalidateReturnsAndRelated(qc: ReturnType<typeof useQueryClient>, orderId?: string, returnId?: string) {
  qc.invalidateQueries({ queryKey: ['returns'] });
  if (orderId) {
    qc.invalidateQueries({ queryKey: ['orders', orderId] });
    qc.invalidateQueries({ queryKey: ['messages', orderId] });
    qc.invalidateQueries({ queryKey: ['purchases'] });
  }
  if (returnId) {
    qc.invalidateQueries({ queryKey: RETURN_KEYS.one(returnId) });
  }
  qc.invalidateQueries({ queryKey: ['notifications', 'unread-count'] });
}

export function useRequestReturn(orderId: string) {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (input: CreateReturnInput) => api.returns.request(orderId, input),
    onSuccess: (resp) => {
      invalidateReturnsAndRelated(qc, orderId, resp.data.id);
    },
  });
}

export function useCancelReturn() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (returnId: string) => api.returns.cancel(returnId),
    onSuccess: (resp) => {
      invalidateReturnsAndRelated(qc, resp.data.order_id, resp.data.id);
    },
  });
}

export function useApproveReturn() {
  const storeId = useSelectedStoreId();
  const qc = useQueryClient();
  return useMutation({
    mutationFn: ({ returnId, restockingFeeCents }: { returnId: string; restockingFeeCents?: number }) =>
      api.returns.forStore(requireSelectedStore(storeId)).approve(returnId, restockingFeeCents ?? 0),
    onSuccess: (resp) => {
      invalidateReturnsAndRelated(qc, resp.data.order_id, resp.data.id);
    },
  });
}

export function useRejectReturn() {
  const storeId = useSelectedStoreId();
  const qc = useQueryClient();
  return useMutation({
    mutationFn: ({ returnId, reasonText }: { returnId: string; reasonText: string }) =>
      api.returns.forStore(requireSelectedStore(storeId)).reject(returnId, reasonText),
    onSuccess: (resp) => {
      invalidateReturnsAndRelated(qc, resp.data.order_id, resp.data.id);
    },
  });
}

export function useMarkReturnReceived() {
  const storeId = useSelectedStoreId();
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (returnId: string) => api.returns.forStore(requireSelectedStore(storeId)).markReceived(returnId),
    onSuccess: (resp) => {
      invalidateReturnsAndRelated(qc, resp.data.order_id, resp.data.id);
    },
  });
}

export function useRetryReturnLabel() {
  const storeId = useSelectedStoreId();
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (returnId: string) => api.returns.forStore(requireSelectedStore(storeId)).retryLabel(returnId),
    onSuccess: (resp) => {
      invalidateReturnsAndRelated(qc, resp.data.order_id, resp.data.id);
    },
  });
}

export function useProactiveRefund(orderId: string) {
  const storeId = useSelectedStoreId();
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (input: ProactiveRefundInput) => api.returns.forStore(requireSelectedStore(storeId)).proactive(orderId, input),
    onSuccess: (resp) => {
      invalidateReturnsAndRelated(qc, orderId, resp.data.id);
    },
  });
}

export function useEscalateReturn() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: ({ returnId, reason }: { returnId: string; reason: string }) =>
      api.returns.escalate(returnId, reason),
    onSuccess: (_resp, { returnId }) => {
      qc.invalidateQueries({ queryKey: RETURN_KEYS.one(returnId) });
      qc.invalidateQueries({ queryKey: ['returns'] });
      qc.invalidateQueries({ queryKey: ['admin', 'returns'] });
    },
  });
}

export function useSellerCloseWithoutRefund() {
  const storeId = useSelectedStoreId();
  const qc = useQueryClient();
  return useMutation({
    mutationFn: ({ returnId, reason }: { returnId: string; reason: string }) =>
      api.returns.forStore(requireSelectedStore(storeId)).sellerCloseWithoutRefund(returnId, reason),
    onSuccess: (resp) => {
      invalidateReturnsAndRelated(qc, resp.data.order_id, resp.data.id);
    },
  });
}

export function useAdminReturnsList(params: AdminReturnsListInput = {}) {
  return useQuery({
    queryKey: ADMIN_RETURN_KEYS.list(params),
    queryFn: () => api.admin.returns.list(params),
    staleTime: 15_000,
  });
}

export function useAdminResolveReturn() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: ({
      returnId,
      action,
      resolution,
    }: {
      returnId: string;
      action: ReturnAdminAction;
      resolution: string;
    }) =>
      api.admin.returns.resolve(returnId, {
        action,
        resolution,
      } satisfies AdminResolveReturnInput),
    onSuccess: (resp) => {
      qc.invalidateQueries({ queryKey: ['admin', 'returns'] });
      qc.invalidateQueries({ queryKey: RETURN_KEYS.one(resp.data.return.id) });
      qc.invalidateQueries({ queryKey: ['orders', resp.data.return.order_id] });
    },
  });
}
