import { Controller, Post, Body, Req, Res, ForbiddenException } from '@nestjs/common';
import { ApiOperation, ApiTags } from '@nestjs/swagger';
import type { Request, Response } from 'express';
import { Public } from '../../common/decorators/public.decorator';
import {
  CurrentUser,
  AuthenticatedUser,
} from '../../common/decorators/current-user.decorator';
import { TelephonyService } from './telephony.service';

/**
 * Twilio 网页拨号端点。
 *   POST /pac/v1/twilio/token  — 客服端拿 Voice AccessToken(需 JWT)
 *   POST /pac/v1/twilio/voice  — Twilio 回调,返回 Dial TwiML(@Public,Twilio 调,无 JWT)
 */
@ApiTags('telephony')
@Controller('twilio')
export class TelephonyController {
  constructor(private readonly telephony: TelephonyService) {}

  @Post('token')
  @ApiOperation({ summary: '签发 Twilio Voice AccessToken(网页点击拨号用)' })
  token(@CurrentUser() user: AuthenticatedUser) {
    if (!this.telephony.isEnabled()) {
      throw new ForbiddenException('网页拨号未配置(缺 Twilio 凭证)');
    }
    return this.telephony.createVoiceToken(user.sub);
  }

  @Public()
  @Post('voice')
  @ApiOperation({ summary: 'Twilio 出站呼叫 TwiML 回调(返回 <Dial>)' })
  async voice(
    @Body() body: Record<string, string>,
    @Req() _req: Request,
    @Res() res: Response,
  ) {
    // ⚠️ 生产应校验 X-Twilio-Signature(需 Auth Token);联调阶段先靠 forceTo + planId 解析收敛风险。
    const twiml = await this.telephony.buildDialTwiml({ planId: body.planId });
    res.type('text/xml').send(twiml);
  }
}
