import { queryOptions } from "@tanstack/react-query";
import { jsonQuery, paginatedJsonQuery } from "../apiAdapter";

export interface CurrencyAmount {
  amount: number;
  currency: string;
}

export interface Invoice {
  id: number;
  invoice_number: string;
  customer_name: string | null;
  status: string;
  issue_date: string;
  due_date: string;
  total: number;
  currency: string;
}

export interface InvoiceStats {
  paid_month: CurrencyAmount[];
  paid_month_czk: number;
  paid_month_count: number;
  awaiting: CurrencyAmount[];
  awaiting_czk: number;
  awaiting_count: number;
  overdue: CurrencyAmount[];
  overdue_czk: number;
  overdue_count: number;
  vat_month: CurrencyAmount[];
  vat_month_czk: number;
}

export interface InvoiceItem {
  id?: number;
  description: string;
  item_description?: string;
  quantity: number;
  unit: string;
  unit_price: number;
  vat_rate?: number;
  is_included_in_total: boolean;
  position?: number;
}

export interface InvoiceSection {
  id?: number;
  title: string | null;
  title_cz: string | null;
  content: string | null;
  position?: number | null;
}

export interface InvoiceDetail {
  id: number;
  invoice_number: string;
  customer_id: number | null;
  customer_name: string;
  customer?: {
    company_id?: string;
    vat_id?: string;
  };
  status: string;
  issue_date: string;
  due_date: string;
  taxable_date?: string;
  tax_date?: string;
  currency: string;
  language: string;
  vat_rate: number;
  apply_vat: boolean;
  exchange_rate: string;
  internal_notes?: string | null;
  payment_method?: string;
  variable_symbol?: string;
  constant_symbol?: string;
  issued_by?: string | null;
  paid_date?: string;
  billing_text?: string;
  bank_name?: string;
  bank_swift?: string;
  bank_iban?: string;
  bank_account?: string;
  bank_account_id?: number | null;
  items?: InvoiceItem[];
  sections?: InvoiceSection[];
  subtotal: number;
  vat_amount: number;
  total: number;
  order?: {
    id: number;
    order_number: string;
    status?: string;
  } | null;
  order_id?: number;
  order_number?: string;
  has_pdf?: boolean;
  valid_transitions?: string[];
}

export interface ReceivedInvoice {
  id: number;
  supplier_name: string;
  invoice_number: string;
  amount: number;
  currency: string;
  vat_rate: number;
  issue_date: string;
  due_date: string;
  notes: string;
  status: string;
  file_name?: string;
  created_at: string;
}

export interface ReceivedStats {
  total_month: CurrencyAmount[];
  total_month_czk: number | null;
  vat_month: CurrencyAmount[];
  vat_month_czk: number | null;
  unpaid: CurrencyAmount[];
  unpaid_czk: number | null;
  unpaid_count: number;
  month_count: number;
}

export const invoiceListOptions = (filters: {
  search?: string;
  sort?: string;
  order?: string;
  page?: number;
  perPage?: number;
  month?: number;
  year?: number;
  status?: string;
}) =>
  queryOptions({
    queryKey: ["invoices", "list", filters],
    queryFn: () => {
      const params = new URLSearchParams();
      if (filters.search) params.set("search", filters.search);
      if (filters.sort) params.set("sort", filters.sort);
      if (filters.order) params.set("order", filters.order);
      if (filters.page) params.set("page", String(filters.page));
      if (filters.perPage) params.set("per_page", String(filters.perPage));
      if (filters.month) params.set("month", String(filters.month));
      if (filters.year) params.set("year", String(filters.year));
      if (filters.status) params.set("status", filters.status);
      const qs = params.toString();
      return paginatedJsonQuery<Invoice>(
        `/api/admin/invoices${qs ? `?${qs}` : ""}`,
      );
    },
  });

export const receivedInvoiceListOptions = (filters: {
  month?: number;
  year?: number;
  search?: string;
  sort?: string;
  order?: string;
  page?: number;
  perPage?: number;
}) =>
  queryOptions({
    queryKey: [
      "invoices",
      "received",
      {
        month: filters.month,
        year: filters.year,
        search: filters.search,
        sort: filters.sort,
        order: filters.order,
        page: filters.page,
        perPage: filters.perPage,
      },
    ],
    queryFn: () => {
      const params = new URLSearchParams();
      if (filters.month) params.set("month", String(filters.month));
      if (filters.year) params.set("year", String(filters.year));
      if (filters.search) params.set("search", filters.search);
      if (filters.sort) params.set("sort", filters.sort);
      if (filters.order) params.set("order", filters.order);
      if (filters.page) params.set("page", String(filters.page));
      if (filters.perPage) params.set("per_page", String(filters.perPage));
      const qs = params.toString();
      return paginatedJsonQuery<ReceivedInvoice>(
        `/api/admin/received-invoices${qs ? `?${qs}` : ""}`,
      );
    },
  });

export const invoiceStatsOptions = (month: number, year: number) =>
  queryOptions({
    queryKey: ["invoices", "stats", month, year],
    queryFn: () =>
      jsonQuery<InvoiceStats>(
        `/api/admin/invoices/stats?month=${month}&year=${year}`,
      ),
  });

// Per-currency total over the WHOLE filtered set of the ISSUED-invoice list.
// Distinct from `invoiceStatsOptions` (the KPI cards) — hits /list-totals and
// passes the same filters the issued list uses (search/status/month/year).
export const invoiceTotalsOptions = (filters: {
  search?: string;
  status?: string;
  month?: number;
  year?: number;
}) =>
  queryOptions({
    queryKey: ["invoices", "list-totals", filters],
    queryFn: async () => {
      const params = new URLSearchParams();
      if (filters.search) params.set("search", filters.search);
      if (filters.status) params.set("status", filters.status);
      if (filters.month) params.set("month", String(filters.month));
      if (filters.year) params.set("year", String(filters.year));
      const qs = params.toString();
      const data = await jsonQuery<{ totals?: CurrencyAmount[] }>(
        `/api/admin/invoices/list-totals${qs ? `?${qs}` : ""}`,
      );
      return data.totals ?? [];
    },
  });

export const receivedInvoiceStatsOptions = (month: number, year: number) =>
  queryOptions({
    queryKey: ["invoices", "received", "stats", month, year],
    queryFn: () =>
      jsonQuery<ReceivedStats>(
        `/api/admin/received-invoices/stats?month=${month}&year=${year}`,
      ),
  });

// Per-currency total over the WHOLE filtered set of the received-invoice list.
// Distinct from `receivedInvoiceStatsOptions` (the KPI cards) — hits
// /list-totals and passes the same filters the received list uses
// (month/year/search). `amount` is GROSS (VAT-inclusive).
export const receivedInvoiceTotalsOptions = (filters: {
  month?: number;
  year?: number;
  search?: string;
}) =>
  queryOptions({
    queryKey: ["invoices", "received", "list-totals", filters],
    queryFn: async () => {
      const params = new URLSearchParams();
      if (filters.month) params.set("month", String(filters.month));
      if (filters.year) params.set("year", String(filters.year));
      if (filters.search) params.set("search", filters.search);
      const qs = params.toString();
      const data = await jsonQuery<{ totals?: CurrencyAmount[] }>(
        `/api/admin/received-invoices/list-totals${qs ? `?${qs}` : ""}`,
      );
      return data.totals ?? [];
    },
  });

export const invoiceDetailOptions = (id: string | undefined) =>
  queryOptions({
    queryKey: ["invoices", id],
    queryFn: () => jsonQuery<InvoiceDetail>(`/api/admin/invoices/${id}`),
    enabled: !!id,
  });
