import {
  Controller,
  Get,
  Post,
  Body,
  Put,
  Param,
  Query,
  ParseIntPipe,
} from '@nestjs/common';
import {
  ApiTags,
  ApiOperation,
  ApiResponse,
  ApiBearerAuth,
  ApiParam,
  ApiQuery,
} from '@nestjs/swagger';
import { TimeTrackingService } from './time-tracking.service';
import { ClockInDto } from './dto/clock-in.dto';
import { ClockOutDto } from './dto/clock-out.dto';
import { CreateTimeEntryDto } from './dto/create-time-entry.dto';
import { UpdateTimeEntryDto } from './dto/update-time-entry.dto';
import { QueryTimeEntriesDto } from './dto/query-time-entries.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/time-tracking')
@ApiBearerAuth('JWT-auth')
@Controller('hr/time')
export class TimeTrackingController {
  constructor(private readonly timeTrackingService: TimeTrackingService) {}

  // =====================================================
  // SELF-SERVICE ENDPOINTS (Employee's own time)
  // =====================================================

  @Post('clock-in')
  @RequirePermissions(Permission.TIME_ENTRIES_CREATE)
  @AuditLog('TimeEntry', 'CLOCK_IN')
  @ApiOperation({ summary: 'Clock in for the current day' })
  @ApiResponse({
    status: 201,
    description: 'Successfully clocked in',
  })
  @ApiResponse({ status: 400, description: 'Bad request - not clocked in or already clocked out' })
  @ApiResponse({ status: 401, description: 'Unauthorized' })
  @ApiResponse({ status: 404, description: 'Employee record not found' })
  @ApiResponse({ status: 409, description: 'Already clocked in for today' })
  clockIn(@CurrentUser() user: JwtPayload, @Body() dto: ClockInDto) {
    return this.timeTrackingService.clockIn(user.sub, dto);
  }

  @Post('clock-out')
  @RequirePermissions(Permission.TIME_ENTRIES_CREATE)
  @AuditLog('TimeEntry', 'CLOCK_OUT')
  @ApiOperation({ summary: 'Clock out for the current day' })
  @ApiResponse({
    status: 201,
    description: 'Successfully clocked out',
  })
  @ApiResponse({ status: 400, description: 'Not clocked in or entry is locked' })
  @ApiResponse({ status: 401, description: 'Unauthorized' })
  @ApiResponse({ status: 404, description: 'Employee record not found' })
  @ApiResponse({ status: 409, description: 'Already clocked out for today' })
  clockOut(@CurrentUser() user: JwtPayload, @Body() dto: ClockOutDto) {
    return this.timeTrackingService.clockOut(user.sub, dto);
  }

  @Post('break/start')
  @RequirePermissions(Permission.TIME_ENTRIES_CREATE)
  @AuditLog('TimeEntry', 'BREAK_START')
  @ApiOperation({ summary: 'Start a break' })
  @ApiResponse({
    status: 201,
    description: 'Break started',
  })
  @ApiResponse({ status: 400, description: 'Not clocked in or already clocked out' })
  @ApiResponse({ status: 401, description: 'Unauthorized' })
  @ApiResponse({ status: 404, description: 'Employee record not found' })
  startBreak(@CurrentUser() user: JwtPayload) {
    return this.timeTrackingService.startBreak(user.sub);
  }

  @Post('break/end')
  @RequirePermissions(Permission.TIME_ENTRIES_CREATE)
  @AuditLog('TimeEntry', 'BREAK_END')
  @ApiOperation({ summary: 'End a break' })
  @ApiResponse({
    status: 201,
    description: 'Break ended',
  })
  @ApiResponse({ status: 400, description: 'No active break found' })
  @ApiResponse({ status: 401, description: 'Unauthorized' })
  @ApiResponse({ status: 404, description: 'Employee record not found' })
  endBreak(@CurrentUser() user: JwtPayload) {
    return this.timeTrackingService.endBreak(user.sub);
  }

  @Get('current')
  @RequirePermissions(Permission.TIME_ENTRIES_VIEW)
  @ApiOperation({ summary: 'Get current time tracking status' })
  @ApiResponse({
    status: 200,
    description: 'Current status (clocked in, on break, today entry)',
  })
  @ApiResponse({ status: 401, description: 'Unauthorized' })
  @ApiResponse({ status: 404, description: 'Employee record not found' })
  getCurrentStatus(@CurrentUser() user: JwtPayload) {
    return this.timeTrackingService.getCurrentStatus(user.sub);
  }

  @Get('entries')
  @RequirePermissions(Permission.TIME_ENTRIES_VIEW)
  @ApiOperation({ summary: 'Get own time entries' })
  @ApiResponse({
    status: 200,
    description: 'List of own time entries',
  })
  @ApiResponse({ status: 401, description: 'Unauthorized' })
  @ApiResponse({ status: 404, description: 'Employee record not found' })
  getMyEntries(
    @CurrentUser() user: JwtPayload,
    @Query() query: QueryTimeEntriesDto,
  ) {
    return this.timeTrackingService.getMyEntries(user.sub, query);
  }

  // =====================================================
  // HR/ADMIN ENDPOINTS (Other employees' time)
  // =====================================================

  @Get('entries/:employeeId')
  @Roles('admin', 'hr-manager', 'team-lead')
  @RequirePermissions(Permission.TIME_ENTRIES_VIEW_ALL)
  @ApiOperation({ summary: 'Get time entries for a specific employee (HR)' })
  @ApiParam({ name: 'employeeId', description: 'Employee ID' })
  @ApiResponse({
    status: 200,
    description: 'List of time entries for the employee',
  })
  @ApiResponse({ status: 401, description: 'Unauthorized' })
  @ApiResponse({ status: 403, description: 'Forbidden - insufficient permissions' })
  @ApiResponse({ status: 404, description: 'Employee not found' })
  getEmployeeEntries(
    @Param('employeeId') employeeId: string,
    @Query() query: QueryTimeEntriesDto,
  ) {
    return this.timeTrackingService.getEntriesByEmployee(employeeId, query);
  }

  @Post('entries')
  @Roles('admin', 'hr-manager')
  @RequirePermissions(Permission.TIME_ENTRIES_CORRECT)
  @AuditLog('TimeEntry', 'CREATE_MANUAL')
  @ApiOperation({ summary: 'Create a manual time entry (correction)' })
  @ApiResponse({
    status: 201,
    description: 'Manual time entry created',
  })
  @ApiResponse({ status: 400, description: 'Validation error or invalid times' })
  @ApiResponse({ status: 401, description: 'Unauthorized' })
  @ApiResponse({ status: 403, description: 'Forbidden - insufficient permissions' })
  @ApiResponse({ status: 404, description: 'Employee not found' })
  @ApiResponse({ status: 409, description: 'Entry already exists for this date' })
  createManualEntry(
    @CurrentUser() user: JwtPayload,
    @Body() dto: CreateTimeEntryDto,
  ) {
    return this.timeTrackingService.createManualEntry(dto, user.sub);
  }

  @Put('entries/:id')
  @Roles('admin', 'hr-manager')
  @RequirePermissions(Permission.TIME_ENTRIES_CORRECT)
  @AuditLog('TimeEntry', 'CORRECT')
  @ApiOperation({ summary: 'Update/correct a time entry' })
  @ApiParam({ name: 'id', description: 'Time Entry ID' })
  @ApiResponse({
    status: 200,
    description: 'Time entry updated',
  })
  @ApiResponse({ status: 400, description: 'Entry is locked or validation error' })
  @ApiResponse({ status: 401, description: 'Unauthorized' })
  @ApiResponse({ status: 403, description: 'Forbidden - insufficient permissions' })
  @ApiResponse({ status: 404, description: 'Time entry not found' })
  updateEntry(
    @CurrentUser() user: JwtPayload,
    @Param('id') id: string,
    @Body() dto: UpdateTimeEntryDto,
  ) {
    return this.timeTrackingService.updateEntry(id, dto, user.sub);
  }

  @Get('summary/:employeeId/:year/:month')
  @Roles('admin', 'hr-manager', 'team-lead')
  @RequirePermissions(Permission.TIME_ENTRIES_VIEW_ALL)
  @ApiOperation({ summary: 'Get monthly time summary for an employee' })
  @ApiParam({ name: 'employeeId', description: 'Employee ID' })
  @ApiParam({ name: 'year', description: 'Year (e.g., 2024)', example: 2024 })
  @ApiParam({ name: 'month', description: 'Month (1-12)', example: 1 })
  @ApiResponse({
    status: 200,
    description: 'Monthly summary with totals and daily breakdown',
  })
  @ApiResponse({ status: 401, description: 'Unauthorized' })
  @ApiResponse({ status: 403, description: 'Forbidden - insufficient permissions' })
  @ApiResponse({ status: 404, description: 'Employee not found' })
  getMonthlySummary(
    @Param('employeeId') employeeId: string,
    @Param('year', ParseIntPipe) year: number,
    @Param('month', ParseIntPipe) month: number,
  ) {
    return this.timeTrackingService.getMonthlySummary(employeeId, year, month);
  }

  @Get('summary/me/:year/:month')
  @RequirePermissions(Permission.TIME_ENTRIES_VIEW)
  @ApiOperation({ summary: 'Get own monthly time summary' })
  @ApiParam({ name: 'year', description: 'Year (e.g., 2024)', example: 2024 })
  @ApiParam({ name: 'month', description: 'Month (1-12)', example: 1 })
  @ApiResponse({
    status: 200,
    description: 'Monthly summary with totals and daily breakdown',
  })
  @ApiResponse({ status: 401, description: 'Unauthorized' })
  @ApiResponse({ status: 404, description: 'Employee record not found' })
  async getMyMonthlySummary(
    @CurrentUser() user: JwtPayload,
    @Param('year', ParseIntPipe) year: number,
    @Param('month', ParseIntPipe) month: number,
  ) {
    const employee = await this.timeTrackingService['getEmployeeByUserId'](
      user.sub,
    );
    return this.timeTrackingService.getMonthlySummary(employee.id, year, month);
  }
}
