import { Controller, Get, Param, Query, Request, Header } from "@nestjs/common";
import { SubscriptionsOrchestrator } from "./subscriptions-orchestrator.service.js";
import {
  subscriptionQuerySchema,
  subscriptionListSchema,
  subscriptionArraySchema,
  subscriptionIdParamSchema,
  subscriptionSchema,
  subscriptionStatsSchema,
} from "@customer-portal/domain/subscriptions";
import type {
  Subscription,
  SubscriptionList,
  SubscriptionStats,
} from "@customer-portal/domain/subscriptions";
import type { InvoiceList } from "@customer-portal/domain/billing";
import { Validation } from "@customer-portal/domain/toolkit";
import { createZodDto, ZodResponse } from "nestjs-zod";
import type { RequestWithUser } from "@bff/modules/auth/auth.types.js";
import { invoiceListSchema } from "@customer-portal/domain/billing";

const subscriptionInvoiceQuerySchema = Validation.createPaginationSchema({
  defaultLimit: 10,
  maxLimit: 100,
  minLimit: 1,
});

// DTOs
class SubscriptionQueryDto extends createZodDto(subscriptionQuerySchema) {}
class SubscriptionInvoiceQueryDto extends createZodDto(subscriptionInvoiceQuerySchema) {}
class SubscriptionIdParamDto extends createZodDto(subscriptionIdParamSchema) {}

// Response DTOs
class SubscriptionListDto extends createZodDto(subscriptionListSchema) {}
class ActiveSubscriptionsDto extends createZodDto(subscriptionArraySchema) {}
class SubscriptionDto extends createZodDto(subscriptionSchema) {}
class SubscriptionStatsDto extends createZodDto(subscriptionStatsSchema) {}
class InvoiceListDto extends createZodDto(invoiceListSchema) {}

/**
 * Subscriptions Controller - Core subscription endpoints
 *
 * Handles basic subscription listing, stats, and invoice retrieval.
 * SIM-specific endpoints are in SimController (sim-management/sim.controller.ts)
 * Internet-specific endpoints are in InternetController (internet-management/internet.controller.ts)
 * Call/SMS history endpoints are in CallHistoryController (call-history/call-history.controller.ts)
 */
@Controller("subscriptions")
export class SubscriptionsController {
  constructor(private readonly subscriptionsOrchestrator: SubscriptionsOrchestrator) {}

  @Get()
  @Header("Cache-Control", "private, max-age=300")
  @ZodResponse({ description: "List subscriptions", type: SubscriptionListDto })
  async getSubscriptions(
    @Request() req: RequestWithUser,
    @Query() query: SubscriptionQueryDto
  ): Promise<SubscriptionList> {
    const { status } = query;
    return this.subscriptionsOrchestrator.getSubscriptions(
      req.user.id,
      status === undefined ? {} : { status }
    );
  }

  @Get("active")
  @Header("Cache-Control", "private, max-age=300")
  @ZodResponse({ description: "List active subscriptions", type: ActiveSubscriptionsDto })
  async getActiveSubscriptions(@Request() req: RequestWithUser): Promise<Subscription[]> {
    return this.subscriptionsOrchestrator.getActiveSubscriptions(req.user.id);
  }

  @Get("stats")
  @Header("Cache-Control", "private, max-age=300")
  @ZodResponse({ description: "Get subscription stats", type: SubscriptionStatsDto })
  async getSubscriptionStats(@Request() req: RequestWithUser): Promise<SubscriptionStats> {
    return this.subscriptionsOrchestrator.getSubscriptionStats(req.user.id);
  }

  @Get(":id")
  @Header("Cache-Control", "private, max-age=300")
  @ZodResponse({ description: "Get subscription", type: SubscriptionDto })
  async getSubscriptionById(
    @Request() req: RequestWithUser,
    @Param() params: SubscriptionIdParamDto
  ): Promise<Subscription> {
    return this.subscriptionsOrchestrator.getSubscriptionById(req.user.id, params.id);
  }

  @Get(":id/invoices")
  @Header("Cache-Control", "private, max-age=60")
  @ZodResponse({ description: "Get subscription invoices", type: InvoiceListDto })
  async getSubscriptionInvoices(
    @Request() req: RequestWithUser,
    @Param() params: SubscriptionIdParamDto,
    @Query() query: SubscriptionInvoiceQueryDto
  ): Promise<InvoiceList> {
    return this.subscriptionsOrchestrator.getSubscriptionInvoices(req.user.id, params.id, query);
  }
}
