import type { AlqoveClient } from '../client';
import type { PaginationLinks, PaginationMeta } from './returns';

export type PayoutState =
  | 'scheduled'
  | 'in_flight'
  | 'succeeded'
  | 'failed'
  | 'void';

export type PayoutLedgerEntryType =
  | 'order_earned'
  | 'order_refunded'
  | 'label_cost_debit'
  | 'payout_settled'
  | 'adjustment_credit'
  | 'adjustment_debit';

export type PayoutLedgerDirection = 'credit' | 'debit';

export interface Payout {
  id: string;
  store_id: string;
  state: PayoutState;
  period_start: string;
  period_end: string;
  scheduled_for: string;
  gross_cents: number;
  debits_cents: number;
  net_cents: number;
  stripe_transfer_id: string | null;
  transferred_at: string | null;
  failed_at: string | null;
  failure_reason: string | null;
  retries: number;
  created_at: string;
  updated_at: string;
}

export interface PayoutLedgerEntry {
  id: string;
  entry_type: PayoutLedgerEntryType;
  direction: PayoutLedgerDirection;
  amount_cents: number;
  description: string | null;
  source_type: string | null;
  source_id: string | null;
  available_at: string;
  created_at: string;
}

export interface PayoutDetail extends Payout {
  entries: PayoutLedgerEntry[];
}

export interface PaginatedPayoutsResponse {
  data: Payout[];
  meta: PaginationMeta;
  links: PaginationLinks;
}

export interface PayoutDetailResponse {
  data: PayoutDetail;
}

export interface ListPayoutsInput {
  state?: PayoutState;
  page?: number;
  per_page?: number;
}

export function createPayoutEndpoints(client: AlqoveClient) {
  return {
    listForStore(storeId: string, params: ListPayoutsInput = {}) {
      const qs = new URLSearchParams();
      if (params.state) qs.set('state', params.state);
      if (params.page) qs.set('page', String(params.page));
      if (params.per_page) qs.set('per_page', String(params.per_page));
      const suffix = qs.toString() ? `?${qs.toString()}` : '';
      return client.get<PaginatedPayoutsResponse>(
        `/v1/stores/${storeId}/payouts${suffix}`,
      );
    },
    getForStore(storeId: string, payoutId: string) {
      return client.get<PayoutDetailResponse>(
        `/v1/stores/${storeId}/payouts/${payoutId}`,
      );
    },
  };
}
