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

// ============================================================================
// TYPES — aligned with State Machine (wiki/concepts/Subscription-State-Machine.md)
// ============================================================================

export type SubscriptionStatus = 'PENDING' | 'SCHEDULED' | 'TRIALING' | 'ACTIVE' | 'PAST_DUE' | 'EXPIRED';
export type BillingPeriod = 'MONTHLY' | 'YEARLY' | 'NONE';

export interface SubscriptionPlan {
  planKey: string;
  selectableByUser: boolean;
  title: string;
  description: string;
  currency: string;
  billingPeriod: BillingPeriod;
  pricePerUserCHF: number;
  pricePerFeatureInstanceCHF: number;
  autoRenew: boolean;
  maxUsers: number | null;
  maxFeatureInstances: number | null;
  includedModules: number;
  maxDataVolumeMB?: number | null;
  budgetAiCHF?: number;
  budgetAiPerUserCHF?: number;
  trialDays: number | null;
  successorPlanKey: string | null;
}

export interface MandateSubscription {
  id: string;
  mandateId: string;
  planKey: string;
  status: SubscriptionStatus;
  recurring: boolean;
  startedAt: string;
  effectiveFrom: string | null;
  endedAt: string | null;
  currentPeriodStart: string | null;
  currentPeriodEnd: string | null;
  trialEndsAt: string | null;
  snapshotPricePerUserCHF: number;
  snapshotPricePerInstanceCHF: number;
  stripeSubscriptionId: string | null;
}

export interface SubscriptionUsage {
  activeUsers: number;
  activeInstances: number;
  usedStorageMB: number;
  maxStorageMB: number | null;
  storagePercent: number | null;
}

export interface SubscriptionStatusResponse {
  active: boolean;
  subscription: MandateSubscription | null;
  plan: SubscriptionPlan | null;
  scheduled: MandateSubscription | null;
  usage: SubscriptionUsage | null;
}

export interface ActivatePlanResponse {
  redirectUrl?: string;
  [key: string]: unknown;
}

export type ApiRequestFunction = (options: ApiRequestOptions<any>) => Promise<any>;

// ============================================================================
// Helpers
// ============================================================================

function _mandateConfig(mandateId?: string): Record<string, any> {
  if (!mandateId) return {};
  return { headers: { 'X-Mandate-Id': mandateId } };
}

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

export async function fetchSelectablePlans(
  request: ApiRequestFunction,
  mandateId?: string,
): Promise<SubscriptionPlan[]> {
  return await request({
    url: '/api/subscription/plans',
    method: 'get',
    additionalConfig: _mandateConfig(mandateId),
  });
}

export async function fetchSubscriptionStatus(
  request: ApiRequestFunction,
  mandateId?: string,
): Promise<SubscriptionStatusResponse> {
  return await request({
    url: '/api/subscription/status',
    method: 'get',
    additionalConfig: _mandateConfig(mandateId),
  });
}

export async function activatePlan(
  request: ApiRequestFunction,
  planKey: string,
  mandateId?: string,
  returnUrl?: string,
): Promise<ActivatePlanResponse> {
  return await request({
    url: '/api/subscription/activate',
    method: 'post',
    data: { planKey, returnUrl: returnUrl || '' },
    additionalConfig: _mandateConfig(mandateId),
  });
}

export async function cancelSubscription(
  request: ApiRequestFunction,
  subscriptionId: string,
  mandateId?: string,
): Promise<Record<string, unknown>> {
  return await request({
    url: '/api/subscription/cancel',
    method: 'post',
    data: { subscriptionId },
    additionalConfig: _mandateConfig(mandateId),
  });
}

export async function reactivateSubscription(
  request: ApiRequestFunction,
  subscriptionId: string,
  mandateId?: string,
): Promise<Record<string, unknown>> {
  return await request({
    url: '/api/subscription/reactivate',
    method: 'post',
    data: { subscriptionId },
    additionalConfig: _mandateConfig(mandateId),
  });
}

export async function verifyCheckout(
  request: ApiRequestFunction,
  sessionId: string,
  mandateId?: string,
): Promise<{ status: string; message: string }> {
  return await request({
    url: '/api/subscription/checkout/verify',
    method: 'post',
    data: { sessionId },
    additionalConfig: _mandateConfig(mandateId),
  });
}
