import type { AlqoveClient } from '../client';
import type { PayoutLedgerDirection, PayoutLedgerEntryType, PayoutState } from './payouts';
import type { PaginationLinks, PaginationMeta } from './returns';

/**
 * Generic ledger row shape returned by the admin/seller ledger and statement
 * endpoints. Same field set as `PayoutLedgerEntry` plus the nullable
 * `payout_id` link.
 */
export interface LedgerEntry {
  id: string;
  entry_type: PayoutLedgerEntryType;
  direction: PayoutLedgerDirection;
  amount_cents: number;
  description: string | null;
  source_type: string | null;
  source_id: string | null;
  available_at: string;
  payout_id: string | null;
  created_at: string;
}

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

export interface ManualAdjustmentAdmin {
  id: string;
  name: string;
  email: string;
}

export interface ManualAdjustment {
  id: string;
  store_id: string;
  type: AdjustmentType;
  amount_cents: number;
  reason: string;
  admin?: ManualAdjustmentAdmin | null;
  created_at: string;
}

export interface AdminPayoutVoidedBy {
  id: string;
  name: string;
  email: string;
}

/**
 * Admin-facing payout shape — mirrors `Payout` columns with the additional
 * `store_name`, `voided_at`, `voided_by`, and `resolution_note` fields the
 * admin queue needs.
 */
export interface AdminPayout {
  id: string;
  store_id: string;
  store_name?: string | null;
  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;
  voided_at: string | null;
  voided_by: AdminPayoutVoidedBy | null;
  resolution_note: string | null;
  created_at: string;
  updated_at: string;
}

export interface FinancialsBalanceStoreRow {
  store_id: string;
  store_name: string | null;
  pending_cents: number;
  available_cents: number;
}

export interface FinancialsBalance {
  total_pending_cents: number;
  total_available_cents: number;
  stores: FinancialsBalanceStoreRow[];
}

export interface PostAdjustmentInput {
  type: AdjustmentType;
  amount_cents: number;
  reason: string;
}

export interface RetryPayoutInput {
  resolution_note?: string | null;
}

export interface VoidPayoutInput {
  resolution_note: string;
}

export interface ListAdminPayoutsInput {
  state?: PayoutState | 'all';
  page?: number;
  per_page?: number;
}

export interface ListLedgerInput {
  page?: number;
  per_page?: number;
  from?: string;
  to?: string;
}

export interface PaginatedLedgerResponse {
  data: LedgerEntry[];
  meta: PaginationMeta;
  links: PaginationLinks;
}

export interface PaginatedAdminPayoutsResponse {
  data: AdminPayout[];
  meta: PaginationMeta;
  links: PaginationLinks;
}

export interface FinancialsBalanceResponse {
  data: FinancialsBalance;
}

export interface ManualAdjustmentResponse {
  data: ManualAdjustment;
}

export interface AdminPayoutResponse {
  data: AdminPayout;
}

export function createAdminFinancialsEndpoints(client: AlqoveClient) {
  return {
    balances() {
      return client.get<FinancialsBalanceResponse>(
        '/v1/admin/financials/balances',
      );
    },
    listPayouts(params: ListAdminPayoutsInput = {}) {
      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<PaginatedAdminPayoutsResponse>(
        `/v1/admin/financials/payouts${suffix}`,
      );
    },
    retryPayout(payoutId: string, body: RetryPayoutInput = {}) {
      return client.post<AdminPayoutResponse>(
        `/v1/admin/payouts/${payoutId}/retry`,
        body,
      );
    },
    voidPayout(payoutId: string, body: VoidPayoutInput) {
      return client.post<AdminPayoutResponse>(
        `/v1/admin/payouts/${payoutId}/void`,
        body,
      );
    },
    storeLedger(storeId: string, params: ListLedgerInput = {}) {
      const qs = new URLSearchParams();
      if (params.page) qs.set('page', String(params.page));
      if (params.per_page) qs.set('per_page', String(params.per_page));
      if (params.from) qs.set('from', params.from);
      if (params.to) qs.set('to', params.to);
      const suffix = qs.toString() ? `?${qs.toString()}` : '';
      return client.get<PaginatedLedgerResponse>(
        `/v1/admin/stores/${storeId}/ledger${suffix}`,
      );
    },
    postAdjustment(storeId: string, body: PostAdjustmentInput) {
      return client.post<ManualAdjustmentResponse>(
        `/v1/admin/stores/${storeId}/ledger-adjustments`,
        body,
      );
    },
  };
}
