/**
 * F-147 — Reporting API client (frontend admin).
 *
 * Wraps the backend reporting endpoints (F-143, F-146).
 * All paths go through /api/* (Next.js proxy).
 */

import { api } from './api-client';

export type ReportingChannel = 'all' | 'ecommerce' | 'pos' | 'admin';
export type ComparisonMode = 'none' | 'previous_equal' | 'previous_calendar';
export type GroupBy = 'day' | 'week' | 'month' | 'hour' | 'store' | 'channel' | 'terminal' | 'cashier' | 'payment';

export interface DateRange {
  from: string;
  to: string;
}

export interface ReportingFilters {
  from: string;
  to: string;
  compare?: ComparisonMode;
  channel?: ReportingChannel;
  storeId?: string | string[];
  terminalId?: string | string[];
  state?: string | string[];
  groupBy?: GroupBy;
  sort?: 'units' | 'revenue';
  page?: number;
  pageSize?: number;
}

export type Availability = 'available' | 'unavailable';

export interface DataAvailability {
  grossSales: Availability;
  netSales: Availability;
  discounts: Availability;
  tax: Availability;
  unitsSold: Availability;
  orders: Availability;
  customers: Availability;
  margin: Availability;
  paymentMethod: Availability;
  refunds: Availability;
  shipping: Availability;
}

export interface Metrics {
  orders: number;
  customers: number;
  grossSalesCents: number;
  discountsCents: number;
  taxCents: number;
  unitsSold: number;
  shippingCents: number;
}

export interface Comparison {
  previous: Metrics;
  variation?: number;
}

export interface SummaryResponse {
  range: DateRange;
  filters: {
    channel: ReportingChannel;
    storeIds: string[];
    terminalIds: string[];
  };
  comparison: Comparison | null;
  dataAvailability: DataAvailability;
  totals: Metrics;
  updatedAt: string;
  cache: { hit: boolean; maxAgeSeconds: number };
}

export interface SalesRow {
  period: string | null;
  channel: ReportingChannel | null;
  storeId: string | null;
  terminalId: string | null;
  metrics: Metrics;
}

export interface ProductRow {
  productId: string;
  productName: string;
  sku: string | null;
  category: string | null;
  brand: string | null;
  metrics: Metrics;
}

export interface ProductsResponse extends Omit<SalesResponse, 'items'> {
  items: ProductRow[];
}

export interface SalesResponse extends SummaryResponse {
  filters: {
    channel: ReportingChannel;
    storeIds: string[];
    terminalIds: string[];
    groupBy: GroupBy | null;
  };
  items: SalesRow[];
  totals: Metrics;
  pagination: {
    page: number;
    pageSize: number;
    totalRows: number;
  };
}

export interface FilterSchema {
  filterSchema: {
    filters: Array<{
      name: string;
      type: string;
      required: boolean;
      repeatable: boolean;
      options?: readonly string[];
      description: string;
    }>;
    comparison: { modes: ComparisonMode[]; rangeBounds: string };
    groupBy: GroupBy[];
    pagination: { pageMin: number; pageSizeMin: number; pageSizeMax: number };
    dataAvailability: DataAvailability;
  };
  permissions: { role: string; grants: string[] };
}

// ── API calls ───────────────────────────────────────────────────────────────

function filtersToQueryString(filters: ReportingFilters): string {
  const params = new URLSearchParams();
  params.set('from', filters.from);
  params.set('to', filters.to);
  if (filters.compare && filters.compare !== 'none') params.set('compare', filters.compare);
  if (filters.channel && filters.channel !== 'all') params.set('channel', filters.channel);
  if (filters.groupBy) params.set('groupBy', filters.groupBy);
  if (filters.sort) params.set('sort', filters.sort);
  if (filters.page) params.set('page', String(filters.page));
  if (filters.pageSize) params.set('pageSize', String(filters.pageSize));
  if (filters.storeId) {
    const ids = Array.isArray(filters.storeId) ? filters.storeId : [filters.storeId];
    ids.forEach((id) => params.append('storeId', id));
  }
  if (filters.terminalId) {
    const ids = Array.isArray(filters.terminalId) ? filters.terminalId : [filters.terminalId];
    ids.forEach((id) => params.append('terminalId', id));
  }
  return params.toString();
}

export const reportingClient = {
  async fetchSchema(): Promise<FilterSchema> {
    return api.get<FilterSchema>('/api/reporting/filters/schema');
  },

  async fetchSummary(filters: ReportingFilters): Promise<SummaryResponse> {
    const qs = filtersToQueryString(filters);
    return api.get<SummaryResponse>(`/api/reporting/summary?${qs}`);
  },

  async fetchSales(filters: ReportingFilters): Promise<SalesResponse> {
    const qs = filtersToQueryString(filters);
    return api.get<SalesResponse>(`/api/reporting/sales?${qs}`);
  },

  async fetchProducts(filters: ReportingFilters): Promise<ProductsResponse> {
    const qs = filtersToQueryString(filters);
    return api.get<ProductsResponse>(`/api/reporting/products?${qs}`);
  },
};
