import { Injectable, Inject, BadRequestException } from "@nestjs/common";
import { Logger } from "nestjs-pino";
import { FreebitOrchestratorService } from "@bff/integrations/freebit/services/freebit-orchestrator.service";
import { SimValidationService } from "./sim-validation.service";
import { SimNotificationService } from "./sim-notification.service";
import { getErrorMessage } from "@bff/core/utils/error.util";
import type { SimCancelRequest } from "../types/sim-requests.types";

@Injectable()
export class SimCancellationService {
  constructor(
    private readonly freebitService: FreebitOrchestratorService,
    private readonly simValidation: SimValidationService,
    private readonly simNotification: SimNotificationService,
    @Inject(Logger) private readonly logger: Logger
  ) {}

  /**
   * Cancel SIM service
   */
  async cancelSim(
    userId: string,
    subscriptionId: number,
    request: SimCancelRequest = {}
  ): Promise<void> {
    try {
      const { account } = await this.simValidation.validateSimSubscription(userId, subscriptionId);

      // Determine run date (PA02-04 requires runDate); default to 1st of next month
      let runDate = request.scheduledAt;
      if (runDate && !/^\d{8}$/.test(runDate)) {
        throw new BadRequestException("Scheduled date must be in YYYYMMDD format");
      }
      if (!runDate) {
        const nextMonth = new Date();
        nextMonth.setMonth(nextMonth.getMonth() + 1);
        nextMonth.setDate(1);
        const y = nextMonth.getFullYear();
        const m = String(nextMonth.getMonth() + 1).padStart(2, "0");
        const d = String(nextMonth.getDate()).padStart(2, "0");
        runDate = `${y}${m}${d}`;
      }

      await this.freebitService.cancelSim(account, runDate);

      this.logger.log(`Successfully cancelled SIM for subscription ${subscriptionId}`, {
        userId,
        subscriptionId,
        account,
        runDate,
      });

      await this.simNotification.notifySimAction("Cancel SIM", "SUCCESS", {
        userId,
        subscriptionId,
        account,
        runDate,
      });
    } catch (error) {
      const sanitizedError = getErrorMessage(error);
      this.logger.error(`Failed to cancel SIM for subscription ${subscriptionId}`, {
        error: sanitizedError,
        userId,
        subscriptionId,
      });
      await this.simNotification.notifySimAction("Cancel SIM", "ERROR", {
        userId,
        subscriptionId,
        error: sanitizedError,
      });
      throw error;
    }
  }
}
