import {
  Body,
  Controller,
  Get,
  Param,
  ParseUUIDPipe,
  Post,
  Query,
} from '@nestjs/common';
import { ApiBearerAuth, ApiOperation, ApiQuery, ApiTags } from '@nestjs/swagger';
import { CurrentUser } from '@edr/api-common';
import type { TCurrentUser } from '@tria-plc/api-common/modules/auth/types/current-user.type';

import { RuleEngineCreate, RuleEngineUpdate, RuleEngineView } from '../../../common/rule-engine-guards';
import { isSuperAdmin } from '../../../common/freight-permission.util';
import {
  DecidePriorityRuleChangeDto,
  SubmitPriorityRuleChangeDto,
} from '../dto/priority-rule-change-request.dto';
import { PriorityRuleChangeStatus } from '../entities/priority-rule-change-request.entity';
import { PriorityRuleChangeRequestsService } from '../services/priority-rule-change-requests.service';

/**
 * Approval workflow for priority-rule changes. Anyone with the manage
 * permission SUBMITS a change; an approver (same permission — the team decides
 * who reviews) approves or rejects it. The team is notified at each step.
 */
@ApiTags('priority-rule-change-requests')
@Controller('priority-rule-change-requests')
@ApiBearerAuth()
export class PriorityRuleChangeRequestsController {
  constructor(private readonly service: PriorityRuleChangeRequestsService) {}

  @Post()
  @RuleEngineCreate('priority-configs')
  @ApiOperation({ summary: 'Submit a priority-rule change for approval' })
  submit(
    @Body() dto: SubmitPriorityRuleChangeDto,
    @CurrentUser() user: TCurrentUser,
  ) {
    return this.service.submit(dto, user?.id);
  }

  @Get()
  @RuleEngineView('priority-configs')
  @ApiQuery({ name: 'status', required: false, enum: ['PENDING', 'APPROVED', 'REJECTED'] })
  @ApiOperation({ summary: 'List priority-rule change requests' })
  list(@Query('status') status?: PriorityRuleChangeStatus) {
    return this.service.list(status);
  }

  @Post(':id/approve')
  @RuleEngineUpdate('priority-configs')
  @ApiOperation({ summary: 'Approve and apply a pending change' })
  approve(
    @Param('id', ParseUUIDPipe) id: string,
    @Body() dto: DecidePriorityRuleChangeDto,
    @CurrentUser() user: TCurrentUser,
  ) {
    // Super admins have full backoffice authority — they may approve a change
    // they submitted; everyone else is held to separation of duties.
    return this.service.approve(id, user?.id, dto.decisionNote, isSuperAdmin(user));
  }

  @Post(':id/reject')
  @RuleEngineUpdate('priority-configs')
  @ApiOperation({ summary: 'Reject a pending change' })
  reject(
    @Param('id', ParseUUIDPipe) id: string,
    @Body() dto: DecidePriorityRuleChangeDto,
    @CurrentUser() user: TCurrentUser,
  ) {
    return this.service.reject(id, user?.id, dto.decisionNote);
  }
}
