import { apiClient } from "@/lib/api";
import { simInfoSchema, type SimInfo, type SimCancelFullRequest, type SimChangePlanFullRequest } from "@customer-portal/domain/sim";
import type {
  SimTopUpRequest,
  SimPlanChangeRequest,
  SimCancelRequest,
} from "@customer-portal/domain/sim";

// Types imported from domain - no duplication
// Domain schemas provide validation rules:
// - SimTopUpRequest: quotaMb (100-51200 MB)
// - SimPlanChangeRequest: newPlanCode, assignGlobalIp, scheduledAt (YYYYMMDD format)
// - SimCancelRequest: scheduledAt (YYYYMMDD format)

export interface AvailablePlan {
  id: string;
  name: string;
  sku: string;
  description?: string;
  monthlyPrice?: number;
  simDataSize?: string;
  simPlanType?: string;
  freebitPlanCode: string;
  isCurrentPlan: boolean;
}

export interface CancellationMonth {
  value: string;
  label: string;
  runDate: string;
}

export interface CancellationPreview {
  simNumber: string;
  serialNumber?: string;
  planCode: string;
  startDate?: string;
  minimumContractEndDate?: string;
  isWithinMinimumTerm: boolean;
  availableMonths: CancellationMonth[];
  customerEmail: string;
  customerName: string;
}

export interface ReissueSimRequest {
  simType: "physical" | "esim";
  newEid?: string;
}

export const simActionsService = {
  async topUp(subscriptionId: string, request: SimTopUpRequest): Promise<void> {
    await apiClient.POST("/api/subscriptions/{subscriptionId}/sim/top-up", {
      params: { path: { subscriptionId } },
      body: request,
    });
  },

  async changePlan(subscriptionId: string, request: SimPlanChangeRequest): Promise<void> {
    await apiClient.POST("/api/subscriptions/{subscriptionId}/sim/change-plan", {
      params: { path: { subscriptionId } },
      body: request,
    });
  },

  async changePlanFull(subscriptionId: string, request: SimChangePlanFullRequest): Promise<{ scheduledAt?: string }> {
    const response = await apiClient.POST<{ success: boolean; message: string; scheduledAt?: string }>(
      "/api/subscriptions/{subscriptionId}/sim/change-plan-full",
      {
        params: { path: { subscriptionId } },
        body: request,
      }
    );
    return { scheduledAt: response.data?.scheduledAt };
  },

  async cancel(subscriptionId: string, request: SimCancelRequest): Promise<void> {
    await apiClient.POST("/api/subscriptions/{subscriptionId}/sim/cancel", {
      params: { path: { subscriptionId } },
      body: request,
    });
  },

  async cancelFull(subscriptionId: string, request: SimCancelFullRequest): Promise<void> {
    await apiClient.POST("/api/subscriptions/{subscriptionId}/sim/cancel-full", {
      params: { path: { subscriptionId } },
      body: request,
    });
  },

  async getSimInfo(subscriptionId: string): Promise<SimInfo | null> {
    const response = await apiClient.GET<SimInfo>("/api/subscriptions/{subscriptionId}/sim", {
      params: { path: { subscriptionId } },
    });

    if (!response.data) {
      return null;
    }

    return simInfoSchema.parse(response.data);
  },

  async getAvailablePlans(subscriptionId: string): Promise<AvailablePlan[]> {
    const response = await apiClient.GET<{ success: boolean; data: AvailablePlan[] }>(
      "/api/subscriptions/{subscriptionId}/sim/available-plans",
      {
        params: { path: { subscriptionId } },
      }
    );
    return response.data?.data || [];
  },

  async getCancellationPreview(subscriptionId: string): Promise<CancellationPreview | null> {
    const response = await apiClient.GET<{ success: boolean; data: CancellationPreview }>(
      "/api/subscriptions/{subscriptionId}/sim/cancellation-preview",
      {
        params: { path: { subscriptionId } },
      }
    );
    return response.data?.data || null;
  },

  async reissueSim(subscriptionId: string, request: ReissueSimRequest): Promise<void> {
    await apiClient.POST("/api/subscriptions/{subscriptionId}/sim/reissue", {
      params: { path: { subscriptionId } },
      body: request,
    });
  },
};
