import {
  Controller,
  Get,
  Post,
  Body,
  Put,
  Param,
  Delete,
  Query,
  HttpCode,
  HttpStatus,
} from '@nestjs/common';
import {
  ApiTags,
  ApiOperation,
  ApiResponse,
  ApiBearerAuth,
  ApiParam,
  ApiQuery,
} from '@nestjs/swagger';
import { EmployeesService } from './employees.service';
import { CreateEmployeeDto } from './dto/create-employee.dto';
import { UpdateEmployeeDto } from './dto/update-employee.dto';
import { QueryEmployeesDto } from './dto/query-employees.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 { CurrentUser } from '../../../auth/decorators/current-user.decorator';
import { JwtPayload } from '../../../auth/interfaces/jwt-payload.interface';

@ApiTags('hr/employees')
@ApiBearerAuth('JWT-auth')
@Controller('hr/employees')
export class EmployeesController {
  constructor(private readonly employeesService: EmployeesService) {}

  @Post()
  @Roles('admin', 'hr-manager')
  @RequirePermissions(Permission.EMPLOYEES_CREATE)
  @AuditLog('Employee', 'CREATE')
  @ApiOperation({ summary: 'Create a new employee record' })
  @ApiResponse({
    status: 201,
    description: 'Employee created successfully',
  })
  @ApiResponse({ status: 400, description: 'Bad request - validation error' })
  @ApiResponse({ status: 401, description: 'Unauthorized' })
  @ApiResponse({ status: 403, description: 'Forbidden - insufficient permissions' })
  @ApiResponse({ status: 404, description: 'User not found' })
  @ApiResponse({ status: 409, description: 'Employee number already exists or user already has employee record' })
  create(@Body() createDto: CreateEmployeeDto) {
    return this.employeesService.create(createDto);
  }

  @Get()
  @RequirePermissions(Permission.EMPLOYEES_VIEW)
  @ApiOperation({ summary: 'Get all employees with pagination and filtering' })
  @ApiResponse({
    status: 200,
    description: 'List of employees (sensitive data redacted)',
  })
  @ApiResponse({ status: 401, description: 'Unauthorized' })
  findAll(@Query() query: QueryEmployeesDto) {
    return this.employeesService.findAll(query);
  }

  @Get('org-chart')
  @RequirePermissions(Permission.EMPLOYEES_VIEW)
  @ApiOperation({ summary: 'Get organizational chart data (hierarchical)' })
  @ApiResponse({
    status: 200,
    description: 'Hierarchical org chart structure',
  })
  @ApiResponse({ status: 401, description: 'Unauthorized' })
  getOrgChart() {
    return this.employeesService.getOrgChart();
  }

  @Get('me')
  @ApiOperation({ summary: 'Get current user employee record' })
  @ApiResponse({
    status: 200,
    description: 'Current user employee record',
  })
  @ApiResponse({ status: 401, description: 'Unauthorized' })
  @ApiResponse({ status: 404, description: 'Employee record not found' })
  async getMyEmployee(@CurrentUser() user: JwtPayload) {
    const employee = await this.employeesService.findByUserId(user.sub);
    if (!employee) {
      return { data: null, message: 'No employee record found for current user' };
    }
    return employee;
  }

  @Get(':id')
  @RequirePermissions(Permission.EMPLOYEES_VIEW)
  @ApiOperation({ summary: 'Get an employee by ID' })
  @ApiParam({ name: 'id', description: 'Employee ID' })
  @ApiResponse({
    status: 200,
    description: 'Employee found (sensitive data redacted)',
  })
  @ApiResponse({ status: 401, description: 'Unauthorized' })
  @ApiResponse({ status: 404, description: 'Employee not found' })
  findOne(@Param('id') id: string) {
    return this.employeesService.findOne(id, false);
  }

  @Get(':id/sensitive')
  @Roles('admin', 'hr-manager')
  @RequirePermissions(Permission.EMPLOYEES_VIEW_ALL)
  @AuditLog('Employee', 'VIEW_SENSITIVE')
  @ApiOperation({ summary: 'Get employee with sensitive data (HR/Admin only)' })
  @ApiParam({ name: 'id', description: 'Employee ID' })
  @ApiResponse({
    status: 200,
    description: 'Employee found with all data including salary and bank account',
  })
  @ApiResponse({ status: 401, description: 'Unauthorized' })
  @ApiResponse({ status: 403, description: 'Forbidden - insufficient permissions' })
  @ApiResponse({ status: 404, description: 'Employee not found' })
  findOneSensitive(@Param('id') id: string) {
    return this.employeesService.findOne(id, true);
  }

  @Get(':id/time-entries')
  @RequirePermissions(Permission.TIME_ENTRIES_VIEW)
  @ApiOperation({ summary: 'Get time entries for an employee' })
  @ApiParam({ name: 'id', description: 'Employee ID' })
  @ApiQuery({ name: 'page', required: false, type: Number })
  @ApiQuery({ name: 'limit', required: false, type: Number })
  @ApiQuery({ name: 'startDate', required: false, type: String, description: 'ISO date string' })
  @ApiQuery({ name: 'endDate', required: false, type: String, description: 'ISO date string' })
  @ApiResponse({
    status: 200,
    description: 'List of time entries for the employee',
  })
  @ApiResponse({ status: 401, description: 'Unauthorized' })
  @ApiResponse({ status: 404, description: 'Employee not found' })
  getTimeEntries(
    @Param('id') id: string,
    @Query('page') page?: number,
    @Query('limit') limit?: number,
    @Query('startDate') startDate?: string,
    @Query('endDate') endDate?: string,
  ) {
    return this.employeesService.getTimeEntries(id, {
      page,
      limit,
      startDate: startDate ? new Date(startDate) : undefined,
      endDate: endDate ? new Date(endDate) : undefined,
    });
  }

  @Put(':id')
  @Roles('admin', 'hr-manager')
  @RequirePermissions(Permission.EMPLOYEES_UPDATE)
  @AuditLog('Employee', 'UPDATE')
  @ApiOperation({ summary: 'Update an employee' })
  @ApiParam({ name: 'id', description: 'Employee ID' })
  @ApiResponse({
    status: 200,
    description: 'Employee updated successfully',
  })
  @ApiResponse({ status: 400, description: 'Bad request - validation error' })
  @ApiResponse({ status: 401, description: 'Unauthorized' })
  @ApiResponse({ status: 403, description: 'Forbidden - insufficient permissions' })
  @ApiResponse({ status: 404, description: 'Employee not found' })
  @ApiResponse({ status: 409, description: 'Employee number already exists' })
  update(@Param('id') id: string, @Body() updateDto: UpdateEmployeeDto) {
    return this.employeesService.update(id, updateDto);
  }

  @Delete(':id')
  @Roles('admin', 'hr-manager')
  @RequirePermissions(Permission.EMPLOYEES_DELETE)
  @AuditLog('Employee', 'DELETE')
  @HttpCode(HttpStatus.OK)
  @ApiOperation({ summary: 'Deactivate an employee (soft delete)' })
  @ApiParam({ name: 'id', description: 'Employee ID' })
  @ApiResponse({
    status: 200,
    description: 'Employee deactivated successfully',
  })
  @ApiResponse({ status: 400, description: 'Employee already deactivated' })
  @ApiResponse({ status: 401, description: 'Unauthorized' })
  @ApiResponse({ status: 403, description: 'Forbidden - insufficient permissions' })
  @ApiResponse({ status: 404, description: 'Employee not found' })
  remove(@Param('id') id: string) {
    return this.employeesService.remove(id);
  }
}
