import { queryOptions } from '@tanstack/react-query'
import { api } from '@/lib/api-client'

// --- Types ---

export interface Transaction {
  id: string
  locationId: string | null
  transactionNumber: string
  accountId: string | null
  repairTicketId: string | null
  repairBatchId: string | null
  transactionType: string
  status: string
  subtotal: string
  discountTotal: string
  taxTotal: string
  total: string
  paymentMethod: string | null
  amountTendered: string | null
  changeGiven: string | null
  checkNumber: string | null
  roundingAdjustment: string
  taxExempt: boolean
  taxExemptReason: string | null
  processedBy: string
  drawerSessionId: string | null
  notes: string | null
  completedAt: string | null
  createdAt: string
  updatedAt: string
  lineItems?: TransactionLineItem[]
}

export interface TransactionLineItem {
  id: string
  transactionId: string
  productId: string | null
  inventoryUnitId: string | null
  description: string
  qty: number
  unitPrice: string
  discountAmount: string
  discountReason: string | null
  taxRate: string
  taxAmount: string
  lineTotal: string
  createdAt: string
}

export interface DrawerSession {
  id: string
  locationId: string | null
  openedBy: string
  closedBy: string | null
  openingBalance: string
  closingBalance: string | null
  expectedBalance: string | null
  overShort: string | null
  denominations: Record<string, number> | null
  status: string
  notes: string | null
  openedAt: string
  closedAt: string | null
}

export interface Discount {
  id: string
  name: string
  discountType: string
  discountValue: string
  appliesTo: string
  requiresApprovalAbove: string | null
  isActive: boolean
}

export interface Product {
  id: string
  name: string
  sku: string | null
  upc: string | null
  description: string | null
  price: string | null
  costPrice: string | null
  qtyOnHand: number | null
  taxCategory: string
  isSerialized: boolean
  isActive: boolean
}

export interface Register {
  id: string
  locationId: string
  name: string
  isActive: boolean
  createdAt: string
  updatedAt: string
}

// --- Query Keys ---

export interface DrawerAdjustment {
  id: string
  drawerSessionId: string
  type: string
  amount: string
  reason: string
  createdBy: string
  createdAt: string
}

export const posKeys = {
  transaction: (id: string) => ['pos', 'transaction', id] as const,
  drawer: (locationId: string) => ['pos', 'drawer', locationId] as const,
  drawerAdjustments: (id: string) => ['pos', 'drawer-adjustments', id] as const,
  drawerReport: (id: string) => ['pos', 'drawer-report', id] as const,
  dailyReport: (locationId: string, date: string) => ['pos', 'daily-report', locationId, date] as const,
  registers: (locationId: string) => ['pos', 'registers', locationId] as const,
  products: (search: string) => ['pos', 'products', search] as const,
  discounts: ['pos', 'discounts'] as const,
}

// --- Query Options ---

export function transactionOptions(id: string | null) {
  return queryOptions({
    queryKey: posKeys.transaction(id ?? ''),
    queryFn: () => api.get<Transaction>(`/v1/transactions/${id}`),
    enabled: !!id,
  })
}

export function currentDrawerOptions(locationId: string | null) {
  return queryOptions({
    queryKey: posKeys.drawer(locationId ?? ''),
    queryFn: async (): Promise<DrawerSession | null> => {
      try {
        return await api.get<DrawerSession>('/v1/drawer/current', { locationId })
      } catch {
        return null // 404 = no open drawer
      }
    },
    enabled: !!locationId,
    retry: false,
  })
}

export function productSearchOptions(search: string) {
  return queryOptions({
    queryKey: posKeys.products(search),
    queryFn: () => api.get<{ data: Product[]; pagination: { page: number; limit: number; total: number; totalPages: number } }>('/v1/products', { q: search, limit: 24, isActive: true, isConsumable: false }),
    enabled: search.length >= 1,
  })
}

export function discountListOptions() {
  return queryOptions({
    queryKey: posKeys.discounts,
    queryFn: () => api.get<Discount[]>('/v1/discounts/all'),
  })
}

export function registerListOptions(locationId: string | null) {
  return queryOptions({
    queryKey: posKeys.registers(locationId ?? ''),
    queryFn: () => api.get<{ data: Register[] }>('/v1/registers/all', { locationId }),
    enabled: !!locationId,
  })
}

export function drawerReportOptions(drawerSessionId: string | null) {
  return queryOptions({
    queryKey: posKeys.drawerReport(drawerSessionId ?? ''),
    queryFn: () => api.get<any>(`/v1/reports/drawer/${drawerSessionId}`),
    enabled: !!drawerSessionId,
  })
}

export function dailyReportOptions(locationId: string | null, date: string) {
  return queryOptions({
    queryKey: posKeys.dailyReport(locationId ?? '', date),
    queryFn: () => api.get<any>('/v1/reports/daily', { locationId, date }),
    enabled: !!locationId && !!date,
  })
}

// --- Mutations ---

export const posMutations = {
  createTransaction: (data: { transactionType: string; locationId?: string; accountId?: string }) =>
    api.post<Transaction>('/v1/transactions', data),

  addLineItem: (txnId: string, data: { productId?: string; inventoryUnitId?: string; description: string; qty: number; unitPrice: number }) =>
    api.post<TransactionLineItem>(`/v1/transactions/${txnId}/line-items`, data),

  removeLineItem: (txnId: string, lineItemId: string) =>
    api.del<TransactionLineItem>(`/v1/transactions/${txnId}/line-items/${lineItemId}`),

  applyDiscount: (txnId: string, data: { discountId?: string; amount: number; reason: string; lineItemId?: string }) =>
    api.post<Transaction>(`/v1/transactions/${txnId}/discounts`, data),

  complete: (txnId: string, data: { paymentMethod: string; amountTendered?: number; checkNumber?: string }) =>
    api.post<Transaction>(`/v1/transactions/${txnId}/complete`, data),

  void: (txnId: string) =>
    api.post<Transaction>(`/v1/transactions/${txnId}/void`, {}),

  openDrawer: (data: { locationId?: string; registerId?: string; openingBalance: number }) =>
    api.post<DrawerSession>('/v1/drawer/open', data),

  closeDrawer: (id: string, data: { closingBalance: number; denominations?: Record<string, number>; notes?: string }) =>
    api.post<DrawerSession>(`/v1/drawer/${id}/close`, data),

  lookupUpc: (upc: string) =>
    api.get<Product>(`/v1/products/lookup/upc/${upc}`),

  addAdjustment: (drawerId: string, data: { type: string; amount: number; reason: string }) =>
    api.post<DrawerAdjustment>(`/v1/drawer/${drawerId}/adjustments`, data),

  getAdjustments: (drawerId: string) =>
    api.get<{ data: DrawerAdjustment[] }>(`/v1/drawer/${drawerId}/adjustments`),

  createFromRepair: (ticketId: string, locationId?: string) =>
    api.post<Transaction>(`/v1/transactions/from-repair/${ticketId}`, { locationId }),
}
