import {
  Controller,
  Get,
  Post,
  Put,
  Delete,
  Body,
  Param,
  Query,
  UseGuards,
  Request,
} from '@nestjs/common';
import { PartGroupsService } from '../services/part-groups.service';
import {
  CreatePartGroupDto,
  UpdatePartGroupDto,
  QueryPartGroupsDto,
  AssignPartsToGroupDto,
  CreateGroupCustomFieldDto,
  UpdateGroupCustomFieldDto,
  PartGroupResponseDto,
  GroupCustomFieldResponseDto,
} from '../dto/part-group.dto';
import { PermissionsGuard } from '@modules/organization/auth/guards/permissions.guard';
import { RequirePermissions } from '@common/decorators/permissions.decorator';
import { Auditable, Sensitive, Financial } from '@core/observability/audit/decorators/auditable.decorator';

@Controller('parts/groups')
export class PartGroupsController {
  constructor(private readonly partGroupsService: PartGroupsService) {}

  // ============================================
  // Part Group CRUD
  // ============================================

  @Post()
  @Auditable()
  @Sensitive()
  @RequirePermissions('parts:update')
  async createGroup(
    @Body() dto: CreatePartGroupDto,
    @Request() req: any,
  ): Promise<PartGroupResponseDto> {
    return this.partGroupsService.createGroup(dto, req.user?.id);
  }

  @Get()
  @RequirePermissions('parts:read')
  async findAllGroups(@Query() query: QueryPartGroupsDto) {
    return this.partGroupsService.findAllGroups(query);
  }

  @Get(':id')
  @RequirePermissions('parts:read')
  async findGroupById(@Param('id') id: string): Promise<PartGroupResponseDto> {
    return this.partGroupsService.findGroupById(id);
  }

  @Put(':id')
  @Auditable()
  @Sensitive()
  @RequirePermissions('parts:update')
  async updateGroup(
    @Param('id') id: string,
    @Body() dto: UpdatePartGroupDto,
    @Request() req: any,
  ): Promise<PartGroupResponseDto> {
    return this.partGroupsService.updateGroup(id, dto, req.user?.id);
  }

  @Delete(':id')
  @Auditable()
  @Sensitive()
  @RequirePermissions('parts:update')
  async deleteGroup(@Param('id') id: string, @Request() req: any): Promise<void> {
    return this.partGroupsService.deleteGroup(id, req.user?.id);
  }

  // ============================================
  // Custom Fields Management
  // ============================================

  @Post(':groupId/fields')
  @Auditable()
  @Sensitive()
  @RequirePermissions('parts:update')
  async addCustomFieldToGroup(
    @Param('groupId') groupId: string,
    @Body() dto: CreateGroupCustomFieldDto,
    @Request() req: any,
  ): Promise<GroupCustomFieldResponseDto> {
    return this.partGroupsService.addCustomFieldToGroup(groupId, dto, req.user?.id);
  }

  @Put('fields/:fieldId')
  @Auditable()
  @Sensitive()
  @RequirePermissions('parts:update')
  async updateCustomField(
    @Param('fieldId') fieldId: string,
    @Body() dto: UpdateGroupCustomFieldDto,
    @Request() req: any,
  ): Promise<GroupCustomFieldResponseDto> {
    return this.partGroupsService.updateCustomField(fieldId, dto, req.user?.id);
  }

  @Delete('fields/:fieldId')
  @Auditable()
  @Sensitive()
  @RequirePermissions('parts:update')
  async deleteCustomField(@Param('fieldId') fieldId: string, @Request() req: any): Promise<void> {
    return this.partGroupsService.deleteCustomField(fieldId, req.user?.id);
  }

  // ============================================
  // Part-Group Assignment
  // ============================================

  @Post(':groupId/parts')
  @Auditable()
  @Sensitive()
  @RequirePermissions('parts:update')
  async assignPartsToGroup(
    @Param('groupId') groupId: string,
    @Body() dto: AssignPartsToGroupDto,
    @Request() req: any,
  ): Promise<void> {
    return this.partGroupsService.assignPartsToGroup(groupId, dto, req.user?.id);
  }

  @Delete(':groupId/parts')
  @Auditable()
  @Sensitive()
  @RequirePermissions('parts:update')
  async removePartsFromGroup(
    @Param('groupId') groupId: string,
    @Body() dto: AssignPartsToGroupDto,
    @Request() req: any,
  ): Promise<void> {
    return this.partGroupsService.removePartsFromGroup(groupId, dto, req.user?.id);
  }

  @Get(':groupId/parts')
  @RequirePermissions('parts:read')
  async getGroupParts(
    @Param('groupId') groupId: string,
    @Query('page') page?: number,
    @Query('limit') limit?: number,
  ) {
    return this.partGroupsService.getGroupParts(groupId, page, limit);
  }
}

