import { ApiRequestOptions } from '../hooks/useApi';

// ============================================================================
// TYPES & INTERFACES
// ============================================================================

export type BillingModel = 'PREPAY_MANDATE' | 'PREPAY_USER';
export type TransactionType = 'CREDIT' | 'DEBIT' | 'ADJUSTMENT';
export type ReferenceType = 'WORKFLOW' | 'PAYMENT' | 'ADMIN' | 'SYSTEM';

export interface BillingBalance {
  mandateId: string;
  mandateName: string;
  billingModel: BillingModel;
  balance: number;
  currency: string;
  warningThreshold: number;
  isWarning: boolean;
}

export interface BillingTransaction {
  id: string;
  accountId: string;
  transactionType: TransactionType;
  amount: number;
  description: string;
  referenceType?: ReferenceType;
  workflowId?: string;
  featureInstanceId?: string;
  featureCode?: string;
  aicoreProvider?: string;
  aicoreModel?: string;
  createdByUserId?: string;
  createdAt?: string;
  mandateId?: string;
  mandateName?: string;
  userId?: string;
  userName?: string;
}

export interface BillingSettings {
  id: string;
  mandateId: string;
  billingModel: BillingModel;
  defaultUserCredit: number;
  warningThresholdPercent: number;
  notifyOnWarning: boolean;
  notifyEmails: string[];
}

export interface BillingSettingsUpdate {
  billingModel?: BillingModel;
  defaultUserCredit?: number;
  warningThresholdPercent?: number;
  notifyOnWarning?: boolean;
  notifyEmails?: string[];
}

export interface UsageReport {
  period: string;
  totalCost: number;
  transactionCount: number;
  costByProvider: Record<string, number>;
  costByModel: Record<string, number>;
  costByFeature: Record<string, number>;
}

export interface AccountSummary {
  id: string;
  mandateId: string;
  userId?: string;
  accountType: string;
  balance: number;
  warningThreshold: number;
  enabled: boolean;
}

export interface CreditAddRequest {
  userId?: string;
  amount: number;
  description?: string;
}

export interface CheckoutCreateRequest {
  userId?: string;
  amount: number;
  returnUrl: string;
}

export interface CheckoutCreateResponse {
  redirectUrl: string;
}

// Type for the request function passed to API functions
export type ApiRequestFunction = (options: ApiRequestOptions<any>) => Promise<any>;

// ============================================================================
// USER API FUNCTIONS
// ============================================================================

/**
 * Fetch billing balances for all mandates the user belongs to
 * Endpoint: GET /api/billing/balance
 */
export async function fetchBalances(
  request: ApiRequestFunction
): Promise<BillingBalance[]> {
  return await request({
    url: '/api/billing/balance',
    method: 'get'
  });
}

/**
 * Fetch billing balance for a specific mandate
 * Endpoint: GET /api/billing/balance/{mandateId}
 */
export async function fetchBalanceForMandate(
  request: ApiRequestFunction,
  mandateId: string
): Promise<BillingBalance> {
  return await request({
    url: `/api/billing/balance/${mandateId}`,
    method: 'get'
  });
}

/**
 * Fetch transaction history
 * Endpoint: GET /api/billing/transactions
 */
export async function fetchTransactions(
  request: ApiRequestFunction,
  limit: number = 50,
  offset: number = 0
): Promise<BillingTransaction[]> {
  return await request({
    url: '/api/billing/transactions',
    method: 'get',
    params: { limit, offset }
  });
}

/**
 * Fetch usage statistics
 * Endpoint: GET /api/billing/statistics/{period}
 */
export async function fetchStatistics(
  request: ApiRequestFunction,
  period: 'day' | 'month' | 'year',
  year: number,
  month?: number
): Promise<UsageReport> {
  const params: Record<string, any> = { year };
  if (month !== undefined) {
    params.month = month;
  }
  
  return await request({
    url: `/api/billing/statistics/${period}`,
    method: 'get',
    params
  });
}

/**
 * Fetch allowed AICore providers
 * Endpoint: GET /api/billing/providers
 */
export async function fetchAllowedProviders(
  request: ApiRequestFunction
): Promise<string[]> {
  return await request({
    url: '/api/billing/providers',
    method: 'get'
  });
}

// ============================================================================
// ADMIN API FUNCTIONS
// ============================================================================

/**
 * Fetch billing settings for a mandate (Admin)
 * Endpoint: GET /api/billing/admin/settings/{mandateId}
 */
export async function fetchSettingsAdmin(
  request: ApiRequestFunction,
  mandateId: string
): Promise<BillingSettings> {
  return await request({
    url: `/api/billing/admin/settings/${mandateId}`,
    method: 'get'
  });
}

/**
 * Create or update billing settings (Admin)
 * Endpoint: POST /api/billing/admin/settings/{mandateId}
 */
export async function updateSettingsAdmin(
  request: ApiRequestFunction,
  mandateId: string,
  settings: BillingSettingsUpdate
): Promise<BillingSettings> {
  return await request({
    url: `/api/billing/admin/settings/${mandateId}`,
    method: 'post',
    data: settings
  });
}

/**
 * Add credit to an account (Admin)
 * Endpoint: POST /api/billing/admin/credit/{mandateId}
 */
export async function addCreditAdmin(
  request: ApiRequestFunction,
  mandateId: string,
  creditRequest: CreditAddRequest
): Promise<BillingTransaction> {
  return await request({
    url: `/api/billing/admin/credit/${mandateId}`,
    method: 'post',
    data: creditRequest
  });
}

/**
 * Create Stripe Checkout Session for credit top-up
 * Endpoint: POST /api/billing/checkout/create/{mandateId}
 */
export async function createCheckoutSession(
  request: ApiRequestFunction,
  mandateId: string,
  checkoutRequest: CheckoutCreateRequest
): Promise<CheckoutCreateResponse> {
  return await request({
    url: `/api/billing/checkout/create/${mandateId}`,
    method: 'post',
    data: checkoutRequest
  });
}

/**
 * Fetch all accounts for a mandate (Admin)
 * Endpoint: GET /api/billing/admin/accounts/{mandateId}
 */
export async function fetchAccountsAdmin(
  request: ApiRequestFunction,
  mandateId: string
): Promise<AccountSummary[]> {
  return await request({
    url: `/api/billing/admin/accounts/${mandateId}`,
    method: 'get'
  });
}

/**
 * Fetch all transactions for a mandate (Admin)
 * Endpoint: GET /api/billing/admin/transactions/{mandateId}
 */
export async function fetchTransactionsAdmin(
  request: ApiRequestFunction,
  mandateId: string,
  limit: number = 100
): Promise<BillingTransaction[]> {
  return await request({
    url: `/api/billing/admin/transactions/${mandateId}`,
    method: 'get',
    params: { limit }
  });
}

/**
 * User summary for billing admin
 */
export interface MandateUserSummary {
  id: string;
  username?: string;
  email?: string;
  firstName?: string;
  lastName?: string;
  displayName?: string;
}

/**
 * Fetch all users for a mandate (Admin)
 * Endpoint: GET /api/billing/admin/users/{mandateId}
 */
export async function fetchUsersForMandateAdmin(
  request: ApiRequestFunction,
  mandateId: string
): Promise<MandateUserSummary[]> {
  return await request({
    url: `/api/billing/admin/users/${mandateId}`,
    method: 'get'
  });
}

// ============================================================================
// MANDATE VIEW TYPES & API FUNCTIONS
// ============================================================================

export interface MandateBalance {
  mandateId: string;
  mandateName: string;
  billingModel: BillingModel;
  totalBalance: number;
  userCount: number;
  defaultUserCredit: number;
  warningThresholdPercent: number;
}

/**
 * Fetch mandate-level balances (SysAdmin only)
 * Endpoint: GET /api/billing/view/mandates/balances
 */
export async function fetchMandateViewBalances(
  request: ApiRequestFunction
): Promise<MandateBalance[]> {
  return await request({
    url: '/api/billing/view/mandates/balances',
    method: 'get'
  });
}

/**
 * Fetch mandate-level transactions (SysAdmin only)
 * Endpoint: GET /api/billing/view/mandates/transactions
 */
export async function fetchMandateViewTransactions(
  request: ApiRequestFunction,
  limit: number = 100
): Promise<BillingTransaction[]> {
  return await request({
    url: '/api/billing/view/mandates/transactions',
    method: 'get',
    params: { limit }
  });
}

// ============================================================================
// USER VIEW TYPES & API FUNCTIONS
// ============================================================================

export interface UserBalance {
  accountId: string;
  mandateId: string;
  mandateName: string;
  userId: string;
  userName: string;
  balance: number;
  warningThreshold: number;
  isWarning: boolean;
  enabled: boolean;
}

export interface UserTransaction extends BillingTransaction {
  userId?: string;
  userName?: string;
}

/**
 * Fetch user-level balances (RBAC-based)
 * Endpoint: GET /api/billing/view/users/balances
 */
export async function fetchUserViewBalances(
  request: ApiRequestFunction
): Promise<UserBalance[]> {
  return await request({
    url: '/api/billing/view/users/balances',
    method: 'get'
  });
}

/**
 * Fetch user-level transactions (RBAC-based)
 * Endpoint: GET /api/billing/view/users/transactions
 */
export async function fetchUserViewTransactions(
  request: ApiRequestFunction,
  limit: number = 100
): Promise<UserTransaction[]> {
  return await request({
    url: '/api/billing/view/users/transactions',
    method: 'get',
    params: { limit }
  });
}
