import {
  Body,
  Controller,
  Delete,
  Get,
  HttpCode,
  HttpStatus,
  Param,
  ParseUUIDPipe,
  Post,
  Put,
  Query,
  UseGuards,
} from '@nestjs/common';
import { JwtAuthGuard } from '@modules/organization/auth/guards/jwt-auth.guard';
import { PermissionsGuard } from '@modules/organization/auth/guards/permissions.guard';
import { RequirePermissions } from '@common/decorators/permissions.decorator';
import { CurrentUser } from '@common/decorators/current-user.decorator';
import type { CurrentUserPayload } from '@common/decorators/current-user.decorator';
import { NIL_ORG_ID } from '@common/constants/nil-uuid';
import { parsePositiveInt } from '@common/utils/query-parsers';
import { Auditable, Financial, Sensitive } from '@core/observability/audit/decorators/auditable.decorator';
import { RobotUnitService } from './services/robot-unit.service';
import { RobotLifecycleService } from './services/robot-lifecycle.service';
import {
  BulkChangeStageDto,
  ChangeStageDto,
  CreateRobotUnitDto,
  HoldStageDto,
  MoveLocationDto,
  ActivateSnDto,
  QueryRobotUnitDto,
  UpdateRobotUnitDto,
} from './dto/robot-unit.dto';

@Controller('robot-manager')
@UseGuards(JwtAuthGuard, PermissionsGuard)
export class RobotUnitController {
  constructor(
    private readonly robotUnitService: RobotUnitService,
    private readonly lifecycleService: RobotLifecycleService,
  ) {}

  @Get()
  @RequirePermissions('robot-manager:read')
  async findAll(@Query() query: QueryRobotUnitDto) {
    return this.robotUnitService.findAll(query);
  }

  @Post()
  @Auditable()
  @RequirePermissions('robot-manager:create')
  async create(
    @Body() dto: CreateRobotUnitDto,
    @CurrentUser() user: CurrentUserPayload,
  ) {
    return this.robotUnitService.create(dto, user.userId, NIL_ORG_ID);
  }

  @Get('by-ffsn/:ffsn')
  @RequirePermissions('robot-manager:read')
  async findByFfsn(@Param('ffsn') ffsn: string) {
    // QR / 二维码深链入口：扫码后 frontend GET 这里拿 id，再 redirect 到 /robot-manager/:id
    return this.robotUnitService.findByFfsn(ffsn);
  }

  @Get(':id')
  @RequirePermissions('robot-manager:read')
  async findOne(@Param('id', new ParseUUIDPipe()) id: string) {
    return this.robotUnitService.findOne(id);
  }

  @Put(':id')
  @Auditable()
  @Financial()
  @RequirePermissions('robot-manager:update')
  async update(
    @Param('id', new ParseUUIDPipe()) id: string,
    @Body() dto: UpdateRobotUnitDto,
    @CurrentUser() user: CurrentUserPayload,
  ) {
    return this.robotUnitService.update(id, dto, user.userId);
  }

  @Delete(':id')
  @Auditable()
  @Sensitive()
  @RequirePermissions('robot-manager:delete')
  async softDelete(
    @Param('id', new ParseUUIDPipe()) id: string,
    @CurrentUser() user: CurrentUserPayload,
  ) {
    return this.robotUnitService.softDelete(id, user.userId);
  }

  // ============ 生命周期编排（v3 替代 v2 的 status controller）============

  @Post(':id/change-stage')
  @HttpCode(HttpStatus.OK)
  @Auditable()
  @RequirePermissions('robot-manager:change-status')
  async changeStage(
    @Param('id', new ParseUUIDPipe()) id: string,
    @Body() dto: ChangeStageDto,
    @CurrentUser() user: CurrentUserPayload,
  ) {
    return this.lifecycleService.changeStage({
      robotUnitId: id,
      toStage: dto.toStage,
      actorUserId: user.userId,
      reason: dto.reason,
      metadata: dto.metadata,
      expectedVersion: dto.version,
    });
  }

  @Post('bulk-change-stage')
  @HttpCode(HttpStatus.OK)
  @Auditable()
  @Sensitive()
  @RequirePermissions('robot-manager:change-status')
  async bulkChangeStage(
    @Body() dto: BulkChangeStageDto,
    @CurrentUser() user: CurrentUserPayload,
  ) {
    return this.lifecycleService.bulkChangeStage(
      dto.robotUnitIds,
      dto.toStage,
      user.userId,
      dto.reason,
    );
  }

  @Post(':id/hold')
  @HttpCode(HttpStatus.OK)
  @Auditable()
  @RequirePermissions('robot-manager:change-status')
  async hold(
    @Param('id', new ParseUUIDPipe()) id: string,
    @Body() dto: HoldStageDto,
    @CurrentUser() user: CurrentUserPayload,
  ) {
    return this.lifecycleService.hold(id, dto.holdReason, user.userId);
  }

  @Post(':id/unhold')
  @HttpCode(HttpStatus.OK)
  @Auditable()
  @RequirePermissions('robot-manager:change-status')
  async unhold(
    @Param('id', new ParseUUIDPipe()) id: string,
    @CurrentUser() user: CurrentUserPayload,
  ) {
    return this.lifecycleService.unhold(id, user.userId);
  }

  @Post(':id/move-location')
  @HttpCode(HttpStatus.OK)
  @Auditable()
  @RequirePermissions('robot-manager:change-status')
  async moveLocation(
    @Param('id', new ParseUUIDPipe()) id: string,
    @Body() dto: MoveLocationDto,
    @CurrentUser() user: CurrentUserPayload,
  ) {
    return this.lifecycleService.moveLocation(id, dto.toLocationId, user.userId, dto.reason);
  }

  /**
   * 占位 SN 激活（07 RECEIVED 扫供应商物理标签）
   * 占位 SN → 正式 FFSN，原值保留 placeholderSnOrig，supplierSn 扫码录入
   * 可选同步推进 stage（dto.advanceTo）
   */
  @Post(':id/activate-sn')
  @HttpCode(HttpStatus.OK)
  @Auditable()
  @RequirePermissions('robot-manager:change-status')
  async activateSn(
    @Param('id', new ParseUUIDPipe()) id: string,
    @Body() dto: ActivateSnDto,
    @CurrentUser() user: CurrentUserPayload,
  ) {
    return this.robotUnitService.activateSn(id, dto, user.userId, NIL_ORG_ID);
  }

  @Get(':id/events')
  @RequirePermissions('robot-manager:read')
  async listEvents(
    @Param('id', new ParseUUIDPipe()) id: string,
    @Query('limit') limit?: string,
  ) {
    return this.lifecycleService.listEvents(id, parsePositiveInt(limit) ?? 50);
  }

  @Get(':id/allowed-next-stages')
  @RequirePermissions('robot-manager:read')
  async allowedNextStages(@Param('id', new ParseUUIDPipe()) id: string) {
    const unit = await this.robotUnitService.findOne(id);
    if (!unit.snapshot) return [];
    return this.lifecycleService.getAllowedNextStages(unit.snapshot.currentStage);
  }
}
