import { apiFetch } from '@client/lib/apiError';

export interface Coupon {
  id: string;
  restaurant_id: string;
  branch_id: string;
  code: string;
  display_name: string | null;
  description: string | null;
  type: 'percent' | 'fixed' | 'bogo';
  value: number;
  bogo_config: Record<string, unknown>;
  valid_from: string | null;
  valid_until: string | null;
  total_redemption_cap: number | null;
  per_customer_cap: number | null;
  min_order_value: number;
  applicable_order_types: string[];
  applicable_channels: string[];
  applicable_branches: string[];
  stack_with_loyalty: boolean;
  stack_with_gift_card: boolean;
  status: 'active' | 'archived';
  created_at: string;
  updated_at: string;
  redemption_count?: number;
}

export interface CouponRedemption {
  id: string;
  coupon_id: string;
  order_id: string | null;
  channel: string;
  discount_amount: number;
  created_at: string;
  customer_id: string | null;
  customer_name?: string | null;
  order_number?: number | null;
}

export interface ListCouponsResponse {
  data: Coupon[];
  total: number;
  page: number;
  limit: number;
  pages: number;
}

export async function listCoupons(params: Record<string, string> = {}) {
  const qs = new URLSearchParams(params).toString();
  return apiFetch(`/api/coupons${qs ? '?' + qs : ''}`) as Promise<ListCouponsResponse>;
}

export async function getCoupon(id: string) {
  return apiFetch(`/api/coupons/${id}`) as Promise<{ coupon: Coupon }>;
}

export async function createCoupon(body: Record<string, unknown>) {
  return apiFetch('/api/coupons', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(body),
  }) as Promise<{ coupon: Coupon }>;
}

export async function updateCoupon(id: string, body: Record<string, unknown>) {
  return apiFetch(`/api/coupons/${id}`, {
    method: 'PATCH',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(body),
  }) as Promise<{ coupon: Coupon }>;
}

export async function archiveCoupon(id: string) {
  return updateCoupon(id, { status: 'archived' });
}

export async function activateCoupon(id: string) {
  return updateCoupon(id, { status: 'active' });
}

export async function deleteCoupon(id: string) {
  return apiFetch(`/api/coupons/${id}`, { method: 'DELETE' }) as Promise<{ success: true }>;
}

export async function duplicateCoupon(id: string) {
  return apiFetch(`/api/coupons/${id}/duplicate`, { method: 'POST' }) as Promise<{ coupon: Coupon }>;
}

export async function listRedemptions(id: string, params: Record<string, string> = {}) {
  const qs = new URLSearchParams(params).toString();
  return apiFetch(`/api/coupons/${id}/redemptions${qs ? '?' + qs : ''}`) as Promise<{
    data: CouponRedemption[]; total: number; page: number; limit: number; pages: number;
  }>;
}

export interface CouponAnalytics {
  totals: {
    redemptions: number;
    discount_value: number;
    orders_discount_total: number;
    reconciled: boolean;
    voice_mentions: number;
  };
  per_day: Array<{ date: string; redemptions: number; discount: number }>;
  top_coupons: Array<{
    coupon_id: string;
    code: string;
    display_name: string | null;
    redemptions: number;
    discount: number;
    voice_mentions?: number;
  }>;
  per_channel: Array<{
    channel: string;
    mentions: number;
    redemptions: number;
    discount: number;
  }>;
  filters: { branch_id: string | null; from: string | null; to: string | null };
}

export async function getCouponAnalytics(params: Record<string, string> = {}) {
  const qs = new URLSearchParams(params).toString();
  return apiFetch(`/api/coupons/analytics${qs ? '?' + qs : ''}`) as Promise<CouponAnalytics>;
}

export function redemptionsCsvUrl(couponId: string): string {
  return `/api/coupons/${couponId}/redemptions?format=csv`;
}

export async function bulkImportCoupons(body: { branch_id: string; rows: Record<string, unknown>[] }) {
  return apiFetch('/api/coupons/bulk-import', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(body),
  }) as Promise<{ created: number; failed: { code: string; error: string }[] }>;
}
