import {
  Controller,
  Get,
  Post,
  Body,
  Put,
  Param,
  Delete,
  Query,
  HttpCode,
  HttpStatus,
  Req,
} from '@nestjs/common';
import {
  ApiTags,
  ApiOperation,
  ApiResponse,
  ApiBearerAuth,
  ApiParam,
  ApiQuery,
} from '@nestjs/swagger';
import { SkillEntriesService } from './skill-entries.service';
import {
  CreateSkillEntryDto,
  UpdateSkillEntryDto,
  BulkSkillEntryDto,
} from './dto';
import { Roles } from '../../../auth/decorators/roles.decorator';
import { RequirePermissions } from '../../../auth/permissions/permissions.decorator';
import { Permission } from '../../../auth/permissions/permissions.enum';
import { AuditLog } from '../../audit/audit.interceptor';
import { Request } from 'express';

interface AuthenticatedRequest extends Request {
  user: {
    id: string;
    email: string;
    [key: string]: any;
  };
}

@ApiTags('lean/skill-matrix')
@ApiBearerAuth('JWT-auth')
@Controller('lean/skill-matrix')
export class SkillEntriesController {
  constructor(private readonly skillEntriesService: SkillEntriesService) {}

  // ==========================================
  // Matrix Views
  // ==========================================

  @Get(':departmentId')
  @RequirePermissions(Permission.SKILLS_VIEW)
  @ApiOperation({ summary: 'Get full skill matrix for a department' })
  @ApiParam({ name: 'departmentId', description: 'Department ID' })
  @ApiResponse({
    status: 200,
    description: 'Skill matrix for the department',
  })
  @ApiResponse({ status: 401, description: 'Unauthorized' })
  @ApiResponse({ status: 404, description: 'Department not found' })
  getMatrixForDepartment(@Param('departmentId') departmentId: string) {
    return this.skillEntriesService.getMatrixForDepartment(departmentId);
  }

  @Get('employee/:employeeId')
  @RequirePermissions(Permission.SKILLS_VIEW)
  @ApiOperation({ summary: 'Get all skills for an employee' })
  @ApiParam({ name: 'employeeId', description: 'Employee ID' })
  @ApiResponse({
    status: 200,
    description: 'Employee skill profile',
  })
  @ApiResponse({ status: 401, description: 'Unauthorized' })
  @ApiResponse({ status: 404, description: 'Employee not found' })
  getEmployeeSkills(@Param('employeeId') employeeId: string) {
    return this.skillEntriesService.getEmployeeSkills(employeeId);
  }

  // ==========================================
  // Analytics
  // ==========================================

  @Get('analysis/:departmentId')
  @RequirePermissions(Permission.SKILLS_VIEW)
  @ApiOperation({ summary: 'Get skill gap analysis for a department' })
  @ApiParam({ name: 'departmentId', description: 'Department ID' })
  @ApiQuery({
    name: 'targetLevel',
    required: false,
    description: 'Target level for comparison (default: 2)',
    type: Number,
  })
  @ApiResponse({
    status: 200,
    description: 'Skill gap analysis',
  })
  @ApiResponse({ status: 401, description: 'Unauthorized' })
  @ApiResponse({ status: 404, description: 'Department not found' })
  analyzeGaps(
    @Param('departmentId') departmentId: string,
    @Query('targetLevel') targetLevel?: number,
  ) {
    return this.skillEntriesService.analyzeGaps(
      departmentId,
      targetLevel ? Number(targetLevel) : 2,
    );
  }

  @Get('gaps/:departmentId')
  @RequirePermissions(Permission.SKILLS_VIEW)
  @ApiOperation({ summary: 'Get skill gaps for a department (alias for analysis)' })
  @ApiParam({ name: 'departmentId', description: 'Department ID' })
  @ApiQuery({
    name: 'targetLevel',
    required: false,
    description: 'Target level for comparison (default: 2)',
    type: Number,
  })
  @ApiResponse({
    status: 200,
    description: 'Skill gaps',
  })
  @ApiResponse({ status: 401, description: 'Unauthorized' })
  @ApiResponse({ status: 404, description: 'Department not found' })
  getGaps(
    @Param('departmentId') departmentId: string,
    @Query('targetLevel') targetLevel?: number,
  ) {
    return this.skillEntriesService.analyzeGaps(
      departmentId,
      targetLevel ? Number(targetLevel) : 2,
    );
  }

  @Get('coverage/:skillId')
  @RequirePermissions(Permission.SKILLS_VIEW)
  @ApiOperation({ summary: 'Get coverage statistics for a skill' })
  @ApiParam({ name: 'skillId', description: 'Skill ID' })
  @ApiResponse({
    status: 200,
    description: 'Skill coverage statistics',
  })
  @ApiResponse({ status: 401, description: 'Unauthorized' })
  @ApiResponse({ status: 404, description: 'Skill not found' })
  getSkillCoverage(@Param('skillId') skillId: string) {
    return this.skillEntriesService.getSkillCoverage(skillId);
  }

  @Get('trainers/:skillId')
  @RequirePermissions(Permission.SKILLS_VIEW)
  @ApiOperation({ summary: 'Get potential trainers for a skill (level 4)' })
  @ApiParam({ name: 'skillId', description: 'Skill ID' })
  @ApiResponse({
    status: 200,
    description: 'List of potential trainers',
  })
  @ApiResponse({ status: 401, description: 'Unauthorized' })
  @ApiResponse({ status: 404, description: 'Skill not found' })
  getTrainers(@Param('skillId') skillId: string) {
    return this.skillEntriesService.getTrainers(skillId);
  }

  // ==========================================
  // CRUD Operations for Entries
  // ==========================================

  @Post('entries')
  @Roles('admin', 'hr-manager', 'team-lead')
  @RequirePermissions(Permission.SKILLS_ASSESS)
  @AuditLog('SkillMatrixEntry', 'CREATE')
  @ApiOperation({ summary: 'Create a new skill assessment' })
  @ApiResponse({
    status: 201,
    description: 'Assessment created successfully',
  })
  @ApiResponse({ status: 400, description: 'Bad request or entry already exists' })
  @ApiResponse({ status: 401, description: 'Unauthorized' })
  @ApiResponse({ status: 403, description: 'Forbidden' })
  @ApiResponse({ status: 404, description: 'Employee or skill not found' })
  createEntry(
    @Body() createDto: CreateSkillEntryDto,
    @Req() req: AuthenticatedRequest,
  ) {
    return this.skillEntriesService.create(createDto, req.user.id);
  }

  @Put('entries/:id')
  @Roles('admin', 'hr-manager', 'team-lead')
  @RequirePermissions(Permission.SKILLS_ASSESS)
  @AuditLog('SkillMatrixEntry', 'UPDATE')
  @ApiOperation({ summary: 'Update a skill assessment' })
  @ApiParam({ name: 'id', description: 'Entry ID' })
  @ApiResponse({
    status: 200,
    description: 'Assessment updated successfully',
  })
  @ApiResponse({ status: 400, description: 'Bad request' })
  @ApiResponse({ status: 401, description: 'Unauthorized' })
  @ApiResponse({ status: 403, description: 'Forbidden' })
  @ApiResponse({ status: 404, description: 'Entry not found' })
  updateEntry(
    @Param('id') id: string,
    @Body() updateDto: UpdateSkillEntryDto,
    @Req() req: AuthenticatedRequest,
  ) {
    return this.skillEntriesService.update(id, updateDto, req.user.id);
  }

  @Delete('entries/:id')
  @Roles('admin', 'hr-manager')
  @RequirePermissions(Permission.SKILLS_MANAGE)
  @AuditLog('SkillMatrixEntry', 'DELETE')
  @HttpCode(HttpStatus.OK)
  @ApiOperation({ summary: 'Delete a skill assessment' })
  @ApiParam({ name: 'id', description: 'Entry ID' })
  @ApiResponse({
    status: 200,
    description: 'Assessment deleted successfully',
  })
  @ApiResponse({ status: 401, description: 'Unauthorized' })
  @ApiResponse({ status: 403, description: 'Forbidden' })
  @ApiResponse({ status: 404, description: 'Entry not found' })
  deleteEntry(@Param('id') id: string) {
    return this.skillEntriesService.remove(id);
  }

  @Post('entries/bulk')
  @Roles('admin', 'hr-manager', 'team-lead')
  @RequirePermissions(Permission.SKILLS_ASSESS)
  @AuditLog('SkillMatrixEntry', 'BULK_UPSERT')
  @ApiOperation({ summary: 'Bulk create or update skill assessments' })
  @ApiResponse({
    status: 201,
    description: 'Assessments processed successfully',
  })
  @ApiResponse({ status: 400, description: 'Bad request' })
  @ApiResponse({ status: 401, description: 'Unauthorized' })
  @ApiResponse({ status: 403, description: 'Forbidden' })
  bulkUpsert(@Body() bulkDto: BulkSkillEntryDto, @Req() req: AuthenticatedRequest) {
    return this.skillEntriesService.bulkUpsert(bulkDto, req.user.id);
  }
}
