import { Controller, Get, Post, Param, Query, Request, Header, UseGuards } from "@nestjs/common";
import { Public } from "@bff/modules/auth/decorators/public.decorator.js";
import { SimCallHistoryService } from "../sim-management/services/support/sim-call-history.service.js";
import { AdminGuard } from "@bff/core/security/guards/admin.guard.js";
import { createZodDto, ZodResponse } from "nestjs-zod";
import type { RequestWithUser } from "@bff/modules/auth/auth.types.js";

import { subscriptionIdParamSchema } from "@customer-portal/domain/subscriptions";
import {
  simHistoryQuerySchema,
  simSftpListQuerySchema,
  simCallHistoryImportQuerySchema,
  simHistoryAvailableMonthsSchema,
  simSftpListResultSchema,
  simCallHistoryImportResultSchema,
  simDomesticCallHistoryResponseSchema,
  simInternationalCallHistoryResponseSchema,
  simSmsHistoryResponseSchema,
  type SimDomesticCallHistoryResponse,
  type SimInternationalCallHistoryResponse,
  type SimSmsHistoryResponse,
} from "@customer-portal/domain/sim";

// DTOs
class SubscriptionIdParamDto extends createZodDto(subscriptionIdParamSchema) {}
class SimHistoryQueryDto extends createZodDto(simHistoryQuerySchema) {}
class SimSftpListQueryDto extends createZodDto(simSftpListQuerySchema) {}
class SimCallHistoryImportQueryDto extends createZodDto(simCallHistoryImportQuerySchema) {}

// Response DTOs
class SimHistoryAvailableMonthsResponseDto extends createZodDto(simHistoryAvailableMonthsSchema) {}
class SimSftpListResultResponseDto extends createZodDto(simSftpListResultSchema) {}
class SimCallHistoryImportResultResponseDto extends createZodDto(
  simCallHistoryImportResultSchema
) {}
class SimDomesticCallHistoryResponseDto extends createZodDto(
  simDomesticCallHistoryResponseSchema
) {}
class SimInternationalCallHistoryResponseDto extends createZodDto(
  simInternationalCallHistoryResponseSchema
) {}
class SimSmsHistoryResponseDto extends createZodDto(simSmsHistoryResponseSchema) {}

@Controller("subscriptions")
export class CallHistoryController {
  constructor(private readonly simCallHistoryService: SimCallHistoryService) {}

  // ==================== Static Routes (must be before :id routes) ====================

  /**
   * Get available months for call/SMS history
   */
  @Public()
  @Get("sim/call-history/available-months")
  @Header("Cache-Control", "public, max-age=3600")
  @ZodResponse({
    description: "Get available call/SMS history months",
    type: SimHistoryAvailableMonthsResponseDto,
  })
  async getAvailableMonths() {
    const months = await this.simCallHistoryService.getAvailableMonths();
    return months;
  }

  /**
   * List available files on SFTP for debugging
   */
  @UseGuards(AdminGuard)
  @Get("sim/call-history/sftp-files")
  @ZodResponse({ description: "List available SFTP files", type: SimSftpListResultResponseDto })
  async listSftpFiles(@Query() query: SimSftpListQueryDto) {
    const files = await this.simCallHistoryService.listSftpFiles(query.path);
    return { files, path: query.path };
  }

  /**
   * Trigger manual import of call history (admin only)
   */
  @UseGuards(AdminGuard)
  @Post("sim/call-history/import")
  @ZodResponse({
    description: "Import call history (admin)",
    type: SimCallHistoryImportResultResponseDto,
  })
  async importCallHistory(@Query() query: SimCallHistoryImportQueryDto) {
    const result = await this.simCallHistoryService.importCallHistory(query.month);
    return result;
  }

  // ==================== Subscription-specific Routes ====================

  /**
   * Get domestic call history
   */
  @Get(":id/sim/call-history/domestic")
  @Header("Cache-Control", "private, max-age=300")
  @ZodResponse({
    description: "Get domestic call history",
    type: SimDomesticCallHistoryResponseDto,
  })
  async getDomesticCallHistory(
    @Request() req: RequestWithUser,
    @Param() params: SubscriptionIdParamDto,
    @Query() query: SimHistoryQueryDto
  ): Promise<SimDomesticCallHistoryResponse> {
    const result = await this.simCallHistoryService.getDomesticCallHistory(
      req.user.id,
      params.id,
      query.month,
      query.page,
      query.limit
    );
    return result;
  }

  /**
   * Get international call history
   */
  @Get(":id/sim/call-history/international")
  @Header("Cache-Control", "private, max-age=300")
  @ZodResponse({
    description: "Get international call history",
    type: SimInternationalCallHistoryResponseDto,
  })
  async getInternationalCallHistory(
    @Request() req: RequestWithUser,
    @Param() params: SubscriptionIdParamDto,
    @Query() query: SimHistoryQueryDto
  ): Promise<SimInternationalCallHistoryResponse> {
    const result = await this.simCallHistoryService.getInternationalCallHistory(
      req.user.id,
      params.id,
      query.month,
      query.page,
      query.limit
    );
    return result;
  }

  /**
   * Get SMS history
   */
  @Get(":id/sim/sms-history")
  @Header("Cache-Control", "private, max-age=300")
  @ZodResponse({ description: "Get SMS history", type: SimSmsHistoryResponseDto })
  async getSmsHistory(
    @Request() req: RequestWithUser,
    @Param() params: SubscriptionIdParamDto,
    @Query() query: SimHistoryQueryDto
  ): Promise<SimSmsHistoryResponse> {
    const result = await this.simCallHistoryService.getSmsHistory(
      req.user.id,
      params.id,
      query.month,
      query.page,
      query.limit
    );
    return result;
  }
}
