import {
  Body,
  Controller,
  Get,
  Param,
  Post,
  Request,
  Sse,
  UsePipes,
  UseGuards,
  UnauthorizedException,
  type MessageEvent,
} from "@nestjs/common";
import { Throttle, ThrottlerGuard } from "@nestjs/throttler";
import { OrderOrchestrator } from "./services/order-orchestrator.service";
import type { RequestWithUser } from "@bff/modules/auth/auth.types";
import { Logger } from "nestjs-pino";
import { ZodValidationPipe } from "@customer-portal/validation/nestjs";
import {
  createOrderRequestSchema,
  orderCreateResponseSchema,
  sfOrderIdParamSchema,
  type CreateOrderRequest,
  type SfOrderIdParam,
} from "@customer-portal/domain/orders";
import { apiSuccessResponseSchema } from "@customer-portal/domain/common";
import { Observable } from "rxjs";
import { OrderEventsService } from "./services/order-events.service";
import { SalesforceReadThrottleGuard } from "@bff/integrations/salesforce/guards/salesforce-read-throttle.guard";
import { SalesforceWriteThrottleGuard } from "@bff/integrations/salesforce/guards/salesforce-write-throttle.guard";

@Controller("orders")
@UseGuards(ThrottlerGuard)
export class OrdersController {
  constructor(
    private orderOrchestrator: OrderOrchestrator,
    private readonly orderEvents: OrderEventsService,
    private readonly logger: Logger
  ) {}

  private readonly createOrderResponseSchema = apiSuccessResponseSchema(orderCreateResponseSchema);

  @Post()
  @UseGuards(SalesforceWriteThrottleGuard)
  @Throttle({ default: { limit: 5, ttl: 60 } }) // 5 order creations per minute
  @UsePipes(new ZodValidationPipe(createOrderRequestSchema))
  async create(@Request() req: RequestWithUser, @Body() body: CreateOrderRequest) {
    this.logger.log(
      {
        userId: req.user?.id,
        orderType: body.orderType,
        skuCount: body.skus?.length || 0,
      },
      "Order creation request received"
    );

    try {
      const result = await this.orderOrchestrator.createOrder(req.user.id, body);
      return this.createOrderResponseSchema.parse({ success: true, data: result });
    } catch (error) {
      this.logger.error(
        {
          error: error instanceof Error ? error.message : String(error),
          userId: req.user?.id,
          orderType: body.orderType,
        },
        "Order creation failed"
      );
      throw error;
    }
  }

  @Get("user")
  @UseGuards(SalesforceReadThrottleGuard)
  async getUserOrders(@Request() req: RequestWithUser) {
    return this.orderOrchestrator.getOrdersForUser(req.user.id);
  }

  @Get(":sfOrderId")
  @UsePipes(new ZodValidationPipe(sfOrderIdParamSchema))
  @UseGuards(SalesforceReadThrottleGuard)
  async get(@Request() req: RequestWithUser, @Param() params: SfOrderIdParam) {
    if (!req.user?.id) {
      throw new UnauthorizedException("Authentication required");
    }
    return this.orderOrchestrator.getOrderForUser(params.sfOrderId, req.user.id);
  }

  @Sse(":sfOrderId/events")
  @UsePipes(new ZodValidationPipe(sfOrderIdParamSchema))
  streamOrderUpdates(@Param() params: SfOrderIdParam): Observable<MessageEvent> {
    return this.orderEvents.subscribe(params.sfOrderId);
  }

  // Note: Order provisioning has been moved to SalesforceProvisioningController
  // This controller now focuses only on customer-facing order operations
}
