import {
  Controller,
  Get,
  Post,
  Put,
  Patch,
  Delete,
  Body,
  Param,
  Query,
  ParseUUIDPipe,
} from '@nestjs/common';
import { ItemsService } from '../services/items.service';
import {
  CreateDevItemDto,
  UpdateDevItemDto,
  UpdateDevItemStatusDto,
  QueryDevItemDto,
} from '../dto';
import { CurrentUser } from '@common/decorators/current-user.decorator';
import { RequirePermissions } from '@common/decorators/permissions.decorator';
import { DEVTRACKER_PERMISSIONS } from '../constants/permissions';

/**
 * 工作项管理控制器
 * 路由前缀: /api/v1/devtracker/items
 */
@Controller('devtracker/items')
export class ItemsController {
  constructor(private readonly itemsService: ItemsService) {}

  private mapItem(item: any, options: { includeContent?: boolean } = {}) {
    const { includeContent = true } = options;
    return {
      id: item.id,
      code: item.code,
      title: item.title,
      description: item.description,
      itemType: item.itemType,
      status: item.status,
      priority: item.priority,
      severity: item.severity,
      moduleKey: item.moduleKey,
      parentId: item.parentId,
      ownerId: item.ownerId,
      reporterId: item.reporterId,
      reviewerId: item.reviewerId,
      reviewedAt: item.reviewedAt,
      startAt: item.startAt,
      devEtaAt: item.devEtaAt,
      testEtaAt: item.testEtaAt,
      etaAt: item.etaAt,
      devCompletedAt: item.devCompletedAt,
      testCompletedAt: item.testCompletedAt,
      completedAt: item.completedAt,
      ...(includeContent ? { content: item.content } : {}),
      labels: item.labels,
      createdAt: item.createdAt,
      updatedAt: item.updatedAt,
    };
  }

  /**
   * 获取工作项列表
   */
  @Get()
  @RequirePermissions(DEVTRACKER_PERMISSIONS.READ)
  async findAll(@Query() query: QueryDevItemDto) {
    const result = await this.itemsService.findAll(query);
    return {
      items: result.items.map((item) => this.mapItem(item, { includeContent: false })),
      pagination: result.pagination,
    };
  }

  /**
   * 获取工作项详情
   */
  @Get(':id')
  @RequirePermissions(DEVTRACKER_PERMISSIONS.READ)
  async findById(@Param('id', ParseUUIDPipe) id: string) {
    const item = await this.itemsService.findById(id);
    return this.mapItem(item);
  }

  /**
   * 创建工作项
   */
  @Post()
  @RequirePermissions(DEVTRACKER_PERMISSIONS.CREATE)
  async create(
    @Body() dto: CreateDevItemDto,
    @CurrentUser('userId') userId: string,
  ) {
    const item = await this.itemsService.create({
      title: dto.title,
      description: dto.description,
      itemType: dto.itemType,
      priority: dto.priority,
      severity: dto.severity,
      moduleKey: dto.moduleKey,
      parentId: dto.parentId,
      ownerId: dto.ownerId,
      devEtaAt: dto.devEtaAt,
      testEtaAt: dto.testEtaAt,
      etaAt: dto.etaAt,
      content: dto.content,
      labels: dto.labels,
      reporterId: userId,
    });
    return this.mapItem(item);
  }

  /**
   * 更新工作项
   */
  @Put(':id')
  @RequirePermissions(DEVTRACKER_PERMISSIONS.UPDATE)
  async update(
    @Param('id', ParseUUIDPipe) id: string,
    @Body() dto: UpdateDevItemDto,
    @CurrentUser('userId') userId: string,
    @CurrentUser('roles') roles: string[],
  ) {
    const item = await this.itemsService.update(id, dto, { userId, roles });
    return this.mapItem(item);
  }

  /**
   * 更新工作项状态
   */
  @Patch(':id/status')
  @RequirePermissions(DEVTRACKER_PERMISSIONS.UPDATE)
  async updateStatus(
    @Param('id', ParseUUIDPipe) id: string,
    @Body() dto: UpdateDevItemStatusDto,
    @CurrentUser('userId') userId: string,
    @CurrentUser('roles') roles: string[],
  ) {
    const item = await this.itemsService.updateStatus(id, dto.status, { userId, roles });
    return this.mapItem(item);
  }

  /**
   * 删除工作项（软删除）
   */
  @Delete(':id')
  @RequirePermissions(DEVTRACKER_PERMISSIONS.DELETE)
  async remove(
    @Param('id', ParseUUIDPipe) id: string,
    @CurrentUser('userId') userId: string,
    @CurrentUser('roles') roles: string[],
  ) {
    const item = await this.itemsService.remove(id, { userId, roles });
    return this.mapItem(item);
  }
}
