import { Body, Controller, Patch, Post, UseGuards } from "@nestjs/common";
import { ApiBearerAuth, ApiOperation, ApiTags } from "@nestjs/swagger";
import { CurrentUser } from "@tria-plc/api-common/modules/auth/decorators/current-user.decorator";
import { JwtGuard } from "@tria-plc/api-common/modules/auth/services/jwt.guard";
import type { TCurrentUser } from "@tria-plc/api-common/modules/auth/types/current-user.type";

import { AccountService } from "./account.service";
import {
  SendContactOtpDto,
  UpdateAccountNameDto,
  UpdateContactDto,
} from "./dto/account.dto";

/**
 * The caller's own account record. Everything here is scoped to the JWT's user
 * id — there is no `:id` parameter to tamper with, so these routes need no
 * permission key beyond being authenticated.
 */
@ApiTags("auth")
@Controller("me")
@ApiBearerAuth()
@UseGuards(JwtGuard)
export class AccountController {
  constructor(private readonly accountService: AccountService) {}

  @Post("contact/otp")
  @ApiOperation({
    summary: "Send a verification code to a new email/phone before changing it",
    description:
      "The code goes to the NEW value supplied here, proving the caller controls " +
      "it. Returns the target masked — an unverified caller never gets it back in full.",
  })
  sendContactOtp(
    @CurrentUser() user: TCurrentUser,
    @Body() dto: SendContactOtpDto,
  ): Promise<{ sentTo: string }> {
    return this.accountService.sendContactOtp(user.id, dto);
  }

  @Patch("contact")
  @ApiOperation({
    summary: "Change the account's email or phone, gated by a verification code",
    description:
      "Verifies the code and writes the new value in one call, so the API never " +
      "has to take a client's word that verification happened.",
  })
  updateContact(
    @CurrentUser() user: TCurrentUser,
    @Body() dto: UpdateContactDto,
  ): Promise<{ success: true; value: string }> {
    return this.accountService.updateContact(user.id, dto);
  }

  @Patch("name")
  @ApiOperation({ summary: "Change the account's display name" })
  updateName(
    @CurrentUser() user: TCurrentUser,
    @Body() dto: UpdateAccountNameDto,
  ): Promise<{ success: true }> {
    return this.accountService.updateName(user.id, dto);
  }
}
