import { findAll } from '../repositories/order.repo.js';
import { findById as findClient, findByIds as findClientsByIds } from '../repositories/client.repo.js';
import { findByClientId as findSealsByClient } from '../repositories/seal.repo.js';
import { findByIds as findProductsByIds } from '../repositories/product.repo.js';
import { findAll as findAllCategories } from '../repositories/productCategory.repo.js';
import { findByIds as findEmployeesByIds } from '../repositories/employee.repo.js';
import { findAll as findAllReturns } from '../repositories/orderReturn.repo.js';
import { findAllForReport as findAllDispatchHistoryForReport } from '../repositories/orderDispatchHistory.repo.js';
import { getStages } from './stage.service.js';
import type { ReportResult, ReportColumn, ReportCell, ReportSummaryField, Order, OrderProduct, OrderStatus, Client, Employee, Product, ProductCategory } from '../types/index.js';

export interface ReportParams {
  dateFrom?: string;
  dateTo?: string;
  clientId?: string;
  employeeId?: string;
  orderNo?: string;
  status?: string;
  stage?: string;
}

function daysSince(dateStr: string): number {
  const d = new Date(dateStr);
  const now = new Date();
  return Math.max(0, Math.floor((now.getTime() - d.getTime()) / (1000 * 60 * 60 * 24)));
}

// Mirrors the frontend's lib/format.ts formatDate exactly, so report output
// matches the mock-data version's rendering (e.g. "13 Jul 2026").
function formatDate(dateStr: string): string {
  return new Date(dateStr).toLocaleDateString('en-IN', { day: '2-digit', month: 'short', year: 'numeric' });
}

function getStatus(order: Order): OrderStatus {
  if (order.lifecycle === 'cancelled') return 'Cancelled';
  const active = order.products.filter((p) => !p.cancelled);
  if (active.length > 0 && active.every((p) => p.dispatched)) return 'Completed';
  return 'Pending';
}

// Every report resolves the same small set of names (client/employee/
// product/category) across potentially thousands of rows. Looking each one
// up with its own DB round-trip (the previous approach) turns a report over
// a large dataset into thousands of sequential queries. Instead, every
// report builder loads this context once up front — a handful of batched
// `WHERE id IN (...)` queries — and every row lookup after that is an
// in-memory Map read.
interface ReportContext {
  clients: Map<string, Client>;
  employees: Map<string, Employee>;
  products: Map<string, Product>;
  categories: Map<string, ProductCategory>;
}

async function buildContext(orders: Order[]): Promise<ReportContext> {
  const clientIds = new Set<string>();
  const employeeIds = new Set<string>();
  const productIds = new Set<string>();

  for (const order of orders) {
    clientIds.add(order.client_id);
    employeeIds.add(order.taken_by_employee_id);
    for (const op of order.products) {
      productIds.add(op.product_id);
      if (op.dispatched_by_employee_id) employeeIds.add(op.dispatched_by_employee_id);
      if (op.cancelled_by_employee_id) employeeIds.add(op.cancelled_by_employee_id);
    }
  }

  const [clientRows, employeeRows, productRows, categoryRows] = await Promise.all([
    findClientsByIds([...clientIds]),
    findEmployeesByIds([...employeeIds]),
    findProductsByIds([...productIds]),
    findAllCategories(),
  ]);

  return {
    clients: new Map(clientRows.map((c) => [c.id, c])),
    employees: new Map(employeeRows.map((e) => [e.id, e])),
    products: new Map(productRows.map((p) => [p.id, p])),
    categories: new Map(categoryRows.map((c) => [c.id, c])),
  };
}

function clientName(ctx: ReportContext, clientId: string): string {
  return ctx.clients.get(clientId)?.name ?? 'Unknown customer';
}

function employeeName(ctx: ReportContext, employeeId: string | undefined): string {
  if (!employeeId) return '—';
  return ctx.employees.get(employeeId)?.name ?? 'Unknown';
}

function productName(ctx: ReportContext, productId: string): string {
  return ctx.products.get(productId)?.name ?? 'Unknown product';
}

function categoryName(ctx: ReportContext, productId: string): string {
  const categoryId = ctx.products.get(productId)?.category_id;
  if (!categoryId) return '—';
  return ctx.categories.get(categoryId)?.name ?? '—';
}

// ---------------------------------------------------------------------------
// Order Reports — one row per order, with full order-level detail.
// ---------------------------------------------------------------------------

const ORDER_COLUMNS: ReportColumn[] = [
  { key: 'sno', header: 'S.No' },
  { key: 'orderNo', header: 'Order No' },
  { key: 'customer', header: 'Customer' },
  { key: 'priority', header: 'Priority' },
  { key: 'daysOpen', header: 'Days Open', align: 'right' },
  { key: 'orderDate', header: 'Order Date' },
  { key: 'deliveryDate', header: 'Delivery' },
  { key: 'qty', header: 'Order Qty', align: 'right' },
  { key: 'weight', header: 'Order Weight', align: 'right' },
  { key: 'dispatchedQty', header: 'Dispatch', align: 'right' },
  { key: 'cancelledQty', header: 'Cancelled Qty', align: 'right' },
  { key: 'cancelledWeight', header: 'Cancelled Weight', align: 'right' },
  { key: 'pendingQty', header: 'Pending Qty', align: 'right' },
  { key: 'pendingWeight', header: 'Pending Weight', align: 'right' },
  { key: 'status', header: 'Status' },
];

function orderTotalQty(order: Order): number {
  return order.products.reduce((s, p) => s + p.quantity, 0);
}
function orderTotalWeight(order: Order): number {
  return order.products.reduce((s, p) => s + p.quantity * p.weight, 0);
}
function orderDispatchedQty(order: Order): number {
  return order.products.reduce((s, p) => s + (p.dispatched_quantity || (p.dispatched ? p.quantity : 0)), 0);
}
function orderCancelledQty(order: Order): number {
  return order.products.reduce((s, p) => s + (p.cancelled_quantity ?? (p.cancelled ? p.quantity : 0)), 0);
}
function orderCancelledWeight(order: Order): number {
  return order.products.reduce((s, p) => s + (p.cancelled_weight ?? (p.cancelled ? p.quantity * p.weight : 0)), 0);
}
function orderPendingQty(order: Order): number {
  return order.products.reduce((s, p) => {
    const cancelledQty = p.cancelled_quantity ?? (p.cancelled ? p.quantity : 0);
    const dispatchedQty = p.dispatched_quantity || (p.dispatched ? p.quantity : 0);
    return s + Math.max(0, p.quantity - cancelledQty - dispatchedQty);
  }, 0);
}
function orderPendingWeight(order: Order): number {
  return order.products.reduce((s, p) => {
    const cancelledWt = p.cancelled_weight ?? (p.cancelled ? p.quantity * p.weight : 0);
    const dispatchedWt = p.dispatched_weight || (p.dispatched ? p.quantity * p.weight : 0);
    return s + Math.max(0, p.quantity * p.weight - cancelledWt - dispatchedWt);
  }, 0);
}

async function buildOrderReport(orders: Order[]): Promise<ReportResult> {
  const ctx = await buildContext(orders);
  const sorted = [...orders].sort((a, b) => a.order_date.localeCompare(b.order_date));
  const rows = sorted.map((order, index) => ({
    sno: index + 1,
    orderNo: order.order_no,
    customer: clientName(ctx, order.client_id),
    priority: order.priority,
    daysOpen: daysSince(order.order_date),
    orderDate: formatDate(order.order_date),
    deliveryDate: formatDate(order.delivery_date),
    qty: orderTotalQty(order),
    weight: orderTotalWeight(order).toFixed(2),
    dispatchedQty: orderDispatchedQty(order),
    cancelledQty: orderCancelledQty(order),
    cancelledWeight: orderCancelledWeight(order).toFixed(2),
    pendingQty: orderPendingQty(order),
    pendingWeight: orderPendingWeight(order).toFixed(2),
    status: getStatus(order),
  }));

  const totals: Record<string, ReportCell> = {
    sno: 'Total',
    orderNo: '',
    customer: `${rows.length} order${rows.length === 1 ? '' : 's'}`,
    priority: '',
    daysOpen: '',
    orderDate: '',
    deliveryDate: '',
    qty: rows.reduce((s, r) => s + Number(r.qty), 0),
    weight: rows.reduce((s, r) => s + Number(r.weight), 0).toFixed(2),
    dispatchedQty: rows.reduce((s, r) => s + Number(r.dispatchedQty), 0),
    cancelledQty: rows.reduce((s, r) => s + Number(r.cancelledQty), 0),
    cancelledWeight: rows.reduce((s, r) => s + Number(r.cancelledWeight), 0).toFixed(2),
    pendingQty: rows.reduce((s, r) => s + Number(r.pendingQty), 0),
    pendingWeight: rows.reduce((s, r) => s + Number(r.pendingWeight), 0).toFixed(2),
    status: '',
  };

  return { columns: ORDER_COLUMNS, rows, totals };
}

async function getDateWiseOrders(params: ReportParams): Promise<ReportResult> {
  const { rows: allOrders } = await findAll({ dateFrom: params.dateFrom, dateTo: params.dateTo, limit: 10000 });
  const filtered = allOrders.filter((o) => !params.status || getStatus(o) === params.status);
  return buildOrderReport(filtered);
}

async function getCustomerWiseOrders(params: ReportParams): Promise<ReportResult> {
  const { rows: allOrders } = await findAll({ clientId: params.clientId, limit: 10000 });
  const filtered = allOrders.filter((o) => !params.status || getStatus(o) === params.status);
  return buildOrderReport(filtered);
}

async function getStaffWiseOrders(params: ReportParams): Promise<ReportResult> {
  const { rows: allOrders } = await findAll({ employeeId: params.employeeId, limit: 10000 });
  const filtered = allOrders.filter((o) => !params.status || getStatus(o) === params.status);
  const base = await buildOrderReport(filtered);
  const ctx = await buildContext(filtered);
  const columns: ReportColumn[] = [...base.columns.slice(0, 3), { key: 'takenBy', header: 'Taken By' }, ...base.columns.slice(3)];
  const ordersByNo = new Map(filtered.map((o) => [o.order_no, o]));
  const rows = base.rows.map((row) => {
    const order = ordersByNo.get(row.orderNo as string);
    return { ...row, takenBy: order ? employeeName(ctx, order.taken_by_employee_id) : '—' };
  });
  return { columns, rows, totals: { ...base.totals, takenBy: '' } };
}

// ---------------------------------------------------------------------------
// Order-wise Report — full detail for a single order, looked up by number.
// ---------------------------------------------------------------------------

const ORDER_PRODUCT_COLUMNS: ReportColumn[] = [
  { key: 'sno', header: 'S.No' },
  { key: 'product', header: 'Item' },
  { key: 'category', header: 'Category' },
  { key: 'hallmarkGrade', header: 'Hallmark Grade' },
  { key: 'qty', header: 'Qty', align: 'right' },
  { key: 'unitWeight', header: 'Weight per Unit', align: 'right' },
  { key: 'totalWeight', header: 'Total Weight', align: 'right' },
  { key: 'size', header: 'Size' },
  { key: 'stage', header: 'Stage' },
  { key: 'note', header: 'Note' },
];

// completed_stages is 1-based (0 = not started, 1 = the first stage just
// entered, ...) so the label lives at completed_stages - 1 in getStages()
// — indexing without that offset (as this used to) reads one stage ahead of
// the line's actual position, and never shows "Not Started" for stage 0.
function productStageLabel(op: OrderProduct): string {
  if (op.cancelled) return 'Cancelled';
  if (op.dispatched) return 'Dispatched';
  if (op.completed_stages <= 0) return 'Not Started';
  return getStages()[op.completed_stages - 1]?.name ?? 'Not Started';
}

function productNote(ctx: ReportContext, op: OrderProduct): string {
  if ((op.dispatched_quantity || 0) > 0 && op.dispatch_date) {
    const by = op.dispatched_by_employee_id ? ` by ${employeeName(ctx, op.dispatched_by_employee_id)}` : '';
    const weight = op.dispatched_weight != null ? ` (${op.dispatched_weight.toFixed(2)} g)` : '';
    return `Dispatched ${op.dispatched_quantity} unit(s)${weight} on ${formatDate(op.dispatch_date)}${by}`;
  }
  if (op.cancelled && op.cancel_date) {
    const by = op.cancelled_by_employee_id ? ` by ${employeeName(ctx, op.cancelled_by_employee_id)}` : '';
    const reason = op.cancel_reason ? ` — ${op.cancel_reason}` : '';
    return `Cancelled ${op.cancelled_quantity ?? op.quantity} unit(s) on ${formatDate(op.cancel_date)}${by}${reason}`;
  }
  return '—';
}

async function getOrderWiseReport(params: ReportParams): Promise<ReportResult> {
  if (!params.orderNo) return { columns: ORDER_PRODUCT_COLUMNS, rows: [], totals: {} };

  const { rows: allOrders } = await findAll({ search: params.orderNo, limit: 10000 });
  const order = allOrders.find((o) => o.order_no === params.orderNo);
  if (!order) return { columns: ORDER_PRODUCT_COLUMNS, rows: [], totals: {} };

  const ctx = await buildContext([order]);
  const client = await findClient(order.client_id);
  const seals = client ? await findSealsByClient(client.id) : [];
  const seal = seals.find((s) => s.id === order.seal_id);

  const summary: ReportSummaryField[] = [
    { label: 'Order No', value: order.order_no },
    { label: 'Order Date', value: formatDate(order.order_date) },
    { label: 'Delivery Date', value: formatDate(order.delivery_date) },
    { label: 'Status', value: getStatus(order) },
    { label: 'Customer', value: client?.name ?? 'Unknown customer' },
    { label: 'Customer Mobile', value: client?.mobile ?? '—' },
    { label: 'Priority', value: order.priority },
    { label: 'Taken By', value: employeeName(ctx, order.taken_by_employee_id) },
    { label: 'Received Through', value: order.received_through },
    { label: 'Received By (Client)', value: order.received_by_client_contact ?? '—' },
    { label: 'S.O. Number', value: order.so_number ?? '—' },
    { label: 'Seal', value: seal?.name ?? '—' },
    { label: 'Remarks', value: order.remarks ?? '—' },
  ];

  const rows = order.products.map((op, index) => ({
    sno: index + 1,
    product: productName(ctx, op.product_id),
    category: categoryName(ctx, op.product_id),
    hallmarkGrade: op.hallmark_grade_name ?? '—',
    qty: op.quantity,
    unitWeight: op.weight,
    totalWeight: (op.quantity * op.weight).toFixed(2),
    size: op.size ?? '—',
    stage: productStageLabel(op),
    note: productNote(ctx, op),
  }));

  const totals: Record<string, ReportCell> = {
    sno: 'Total',
    product: '',
    category: `${rows.length} item line${rows.length === 1 ? '' : 's'}`,
    hallmarkGrade: '',
    qty: rows.reduce((s, r) => s + Number(r.qty), 0),
    unitWeight: '',
    totalWeight: rows.reduce((s, r) => s + Number(r.totalWeight), 0).toFixed(2),
    size: '',
    stage: '',
    note: '',
  };

  return { columns: ORDER_PRODUCT_COLUMNS, rows, totals, summary };
}

// ---------------------------------------------------------------------------
// Production Report — one row per product line still in manufacturing,
// optionally narrowed to whichever single stage it's currently sitting at.
// ---------------------------------------------------------------------------

const STAGE_COLUMNS: ReportColumn[] = [
  { key: 'sno', header: 'S.No' },
  { key: 'orderNo', header: 'Order No' },
  { key: 'orderDate', header: 'Order Date' },
  { key: 'deliveryDate', header: 'Delivery Date' },
  { key: 'customer', header: 'Customer' },
  { key: 'product', header: 'Item' },
  { key: 'category', header: 'Category' },
  { key: 'hallmarkGrade', header: 'Hallmark Grade' },
  { key: 'qty', header: 'Qty', align: 'right' },
  { key: 'unitWeight', header: 'Weight per Unit', align: 'right' },
  { key: 'totalWeight', header: 'Total Weight', align: 'right' },
  { key: 'size', header: 'Size' },
  { key: 'daysPending', header: 'Days Pending', align: 'right' },
  { key: 'currentStage', header: 'Current Stage' },
];

async function getProductionReportData(params: ReportParams): Promise<ReportResult> {
  const { rows: allOrders } = await findAll({
    clientId: params.clientId,
    dateFrom: params.dateFrom,
    dateTo: params.dateTo,
    limit: 10000,
  });

  const ctx = await buildContext(allOrders);
  const rows: Record<string, ReportCell>[] = [];

  for (const order of allOrders) {
    if (order.lifecycle !== 'active') continue;
    for (const op of order.products) {
      if (op.dispatched || op.cancelled) continue;
      // Same 1-based offset as productStageLabel: completed_stages - 1 is
      // the index of the stage this line is currently sitting at, with 0
      // ("not started") having no corresponding stage entry.
      const currentStage = op.completed_stages > 0 ? getStages()[op.completed_stages - 1] : undefined;
      if (params.stage && currentStage?.id !== params.stage) continue;

      rows.push({
        sno: rows.length + 1,
        orderNo: order.order_no,
        orderDate: formatDate(order.order_date),
        deliveryDate: formatDate(order.delivery_date),
        customer: clientName(ctx, order.client_id),
        product: productName(ctx, op.product_id),
        category: categoryName(ctx, op.product_id),
        hallmarkGrade: op.hallmark_grade_name ?? '—',
        qty: op.quantity,
        unitWeight: op.weight,
        totalWeight: (op.quantity * op.weight).toFixed(2),
        size: op.size ?? '—',
        daysPending: daysSince(order.order_date),
        currentStage: currentStage?.name ?? 'Not Started',
      });
    }
  }

  const totals: Record<string, ReportCell> = {
    sno: 'Total',
    orderNo: '',
    orderDate: '',
    deliveryDate: '',
    customer: `${rows.length} line item${rows.length === 1 ? '' : 's'}`,
    product: '',
    category: '',
    hallmarkGrade: '',
    qty: rows.reduce((s, r) => s + Number(r.qty), 0),
    unitWeight: '',
    totalWeight: rows.reduce((s, r) => s + Number(r.totalWeight), 0).toFixed(2),
    size: '',
    daysPending: '',
    currentStage: '',
  };
  return { columns: STAGE_COLUMNS, rows, totals };
}

// ---------------------------------------------------------------------------
// Dispatch Report — one row per dispatched product line.
// ---------------------------------------------------------------------------

const DISPATCH_COLUMNS: ReportColumn[] = [
  { key: 'sno', header: 'S.No' },
  { key: 'orderNo', header: 'Order No' },
  { key: 'orderDate', header: 'Order Date' },
  { key: 'customer', header: 'Customer' },
  { key: 'product', header: 'Item' },
  { key: 'hallmarkGrade', header: 'Hallmark Grade' },
  { key: 'qty', header: 'Qty', align: 'right' },
  { key: 'unitWeight', header: 'Weight per Unit', align: 'right' },
  { key: 'totalWeight', header: 'Total Weight', align: 'right' },
  { key: 'size', header: 'Size' },
  { key: 'dispatchDate', header: 'Dispatch Date' },
  { key: 'dispatchedBy', header: 'Dispatched By' },
  { key: 'receivedBy', header: 'Received By' },
];

function toDateStr(value: unknown): string {
  return (value instanceof Date ? value.toISOString() : String(value)).slice(0, 10);
}

// Sourced from order_dispatch_history — the append-only ledger of actual
// dispatch events — rather than order_products' live dispatched_quantity/
// dispatch_date columns. Those live columns are decremented by an approved
// return (see orderReturn.service.ts's approve()), so building this report
// from them would retroactively shrink a past dispatch date's quantity
// once a return later reduces the running total. The ledger is never
// touched by a return, so every batch keeps its real, original figures —
// and a line dispatched in several partial batches correctly shows as
// several rows here (one per batch) instead of being collapsed into one.
async function getDispatchReportData(params: ReportParams): Promise<ReportResult> {
  const allEvents = await findAllDispatchHistoryForReport();

  const entries: { sortKey: string; row: Record<string, ReportCell> }[] = [];

  for (const ev of allEvents) {
    if (params.clientId && ev.client_id !== params.clientId) continue;
    const dispatchDate = toDateStr(ev.dispatch_date);
    if (params.dateFrom && dispatchDate < params.dateFrom) continue;
    if (params.dateTo && dispatchDate > params.dateTo) continue;

    entries.push({
      sortKey: dispatchDate,
      row: {
        sno: 0,
        orderNo: ev.order_no,
        orderDate: formatDate(toDateStr(ev.order_date)),
        customer: ev.client_name,
        product: ev.product_name,
        hallmarkGrade: ev.hallmark_grade_name ?? '—',
        qty: ev.quantity,
        unitWeight: ev.quantity > 0 ? ev.weight / ev.quantity : ev.weight,
        totalWeight: ev.weight.toFixed(2),
        size: ev.size ?? '—',
        dispatchDate: formatDate(dispatchDate),
        dispatchedBy: ev.dispatched_by_name,
        receivedBy: ev.received_by_name ?? '—',
      },
    });
  }

  entries.sort((a, b) => a.sortKey.localeCompare(b.sortKey));
  const rows: Record<string, ReportCell>[] = entries.map((e, i) => ({ ...e.row, sno: i + 1 }));

  const totals: Record<string, ReportCell> = {
    sno: 'Total',
    orderNo: '',
    orderDate: '',
    customer: `${rows.length} dispatch${rows.length === 1 ? '' : 'es'}`,
    product: '',
    hallmarkGrade: '',
    qty: rows.reduce((s, r) => s + Number(r.qty), 0),
    unitWeight: '',
    totalWeight: rows.reduce((s, r) => s + Number(r.totalWeight), 0).toFixed(2),
    size: '',
    dispatchDate: '',
    dispatchedBy: '',
    receivedBy: '',
  };
  return { columns: DISPATCH_COLUMNS, rows, totals };
}

// ---------------------------------------------------------------------------
// Returned Items Report — one row per return request, across every status.
// ---------------------------------------------------------------------------

const RETURN_COLUMNS: ReportColumn[] = [
  { key: 'sno', header: 'S.No' },
  { key: 'orderNo', header: 'Order No' },
  { key: 'joNo', header: 'JO No' },
  { key: 'product', header: 'Item' },
  { key: 'returnedQty', header: 'Returned Qty', align: 'right' },
  { key: 'returnedWeight', header: 'Returned Weight', align: 'right' },
  { key: 'returnedDate', header: 'Returned Date & Time' },
  { key: 'reason', header: 'Reason' },
  { key: 'targetStage', header: 'Target Stage' },
  { key: 'requestedBy', header: 'Requested By' },
  { key: 'requestedAt', header: 'Requested At' },
  { key: 'approvedBy', header: 'Approved By' },
  { key: 'approvedAt', header: 'Approved At' },
  { key: 'status', header: 'Status' },
  { key: 'nextDeliveryDate', header: 'Next Delivery Date' },
];

function formatDateTime(value: string | undefined): string {
  if (!value) return '—';
  return new Date(value).toLocaleString('en-IN', { day: '2-digit', month: 'short', year: 'numeric', hour: '2-digit', minute: '2-digit' });
}

async function getReturnedItemsReport(params: ReportParams): Promise<ReportResult> {
  const returns = await findAllReturns({
    status: params.status ? params.status.toLowerCase() : undefined,
    dateFrom: params.dateFrom,
    dateTo: params.dateTo,
  });

  const rows = returns.map((r, index) => ({
    sno: index + 1,
    orderNo: r.order_no ?? '—',
    joNo: r.jo_no ?? '—',
    product: r.product_name ?? 'Unknown product',
    returnedQty: r.returned_quantity,
    returnedWeight: r.returned_weight.toFixed(3),
    returnedDate: formatDateTime(r.returned_date),
    reason: r.reason,
    targetStage: r.target_stage_name ?? '—',
    requestedBy: r.requested_by_employee_name ?? '—',
    requestedAt: formatDateTime(r.requested_at),
    approvedBy: r.approved_by_employee_name ?? '—',
    approvedAt: r.approved_at ? formatDateTime(r.approved_at) : '—',
    status: r.status.charAt(0).toUpperCase() + r.status.slice(1),
    nextDeliveryDate: r.next_delivery_date ? formatDate(r.next_delivery_date) : '—',
  }));

  const totals: Record<string, ReportCell> = {
    sno: 'Total',
    orderNo: '',
    joNo: '',
    product: `${rows.length} return${rows.length === 1 ? '' : 's'}`,
    returnedQty: rows.reduce((s, r) => s + Number(r.returnedQty), 0),
    returnedWeight: rows.reduce((s, r) => s + Number(r.returnedWeight), 0).toFixed(3),
    returnedDate: '',
    reason: '',
    targetStage: '',
    requestedBy: '',
    requestedAt: '',
    approvedBy: '',
    approvedAt: '',
    status: '',
    nextDeliveryDate: '',
  };

  return { columns: RETURN_COLUMNS, rows, totals };
}

// ---------------------------------------------------------------------------

export async function getOrderReport(reportId: string, params: ReportParams): Promise<ReportResult> {
  switch (reportId) {
    case 'date-wise':
      return getDateWiseOrders(params);
    case 'customer-wise':
      return getCustomerWiseOrders(params);
    case 'staff-wise':
      return getStaffWiseOrders(params);
    case 'order-wise':
      return getOrderWiseReport(params);
    case 'returned-items':
      return getReturnedItemsReport(params);
    default:
      return { columns: [], rows: [], totals: {} };
  }
}

export async function getProductionReport(reportId: string, params: ReportParams): Promise<ReportResult> {
  if (reportId !== 'production-report') return { columns: STAGE_COLUMNS, rows: [], totals: {} };
  return getProductionReportData(params);
}

export async function getDispatchReport(reportId: string, params: ReportParams): Promise<ReportResult> {
  if (reportId !== 'dispatch-report') return { columns: DISPATCH_COLUMNS, rows: [], totals: {} };
  return getDispatchReportData(params);
}
