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 { MorningMeetingService } from './morning-meeting.service';
import {
  CreateMeetingDto,
  UpdateMeetingDto,
  QueryMeetingsDto,
  CreateTopicDto,
  UpdateTopicDto,
  CreateActionDto,
  UpdateActionDto,
} from './dto';
import { RequirePermissions } from '../../../auth/permissions/permissions.decorator';
import { Permission } from '../../../auth/permissions/permissions.enum';
import { AuditLog } from '../../audit/audit.interceptor';
import { SQCDMCategory } from '@prisma/client';

@ApiTags('lean/meetings')
@ApiBearerAuth('JWT-auth')
@Controller('lean/meetings')
export class MorningMeetingController {
  constructor(private readonly meetingService: MorningMeetingService) {}

  // ============================================================================
  // MEETING ENDPOINTS
  // ============================================================================

  @Post()
  @RequirePermissions(Permission.MEETING_CREATE)
  @AuditLog('MorningMeeting', 'CREATE')
  @ApiOperation({ summary: 'Create a new morning meeting' })
  @ApiResponse({ status: 201, description: 'Meeting created successfully' })
  @ApiResponse({ status: 400, description: 'Bad request' })
  @ApiResponse({ status: 404, description: 'Department not found' })
  @ApiResponse({ status: 409, description: 'Meeting already exists for this date' })
  createMeeting(@Body() createDto: CreateMeetingDto) {
    return this.meetingService.createMeeting(createDto);
  }

  @Get()
  @RequirePermissions(Permission.MEETING_VIEW)
  @ApiOperation({ summary: 'Get all meetings with pagination and filters' })
  @ApiResponse({ status: 200, description: 'List of meetings' })
  findAllMeetings(@Query() query: QueryMeetingsDto) {
    return this.meetingService.findAllMeetings(query);
  }

  @Get('actions/open')
  @RequirePermissions(Permission.MEETING_VIEW)
  @ApiOperation({ summary: 'Get all open action items' })
  @ApiQuery({
    name: 'departmentId',
    required: false,
    description: 'Filter by department',
  })
  @ApiResponse({ status: 200, description: 'List of open actions' })
  getOpenActions(@Query('departmentId') departmentId?: string) {
    return this.meetingService.getOpenActions(departmentId);
  }

  @Get('today/:departmentId')
  @RequirePermissions(Permission.MEETING_VIEW)
  @ApiOperation({ summary: 'Get today\'s meeting for a department' })
  @ApiParam({ name: 'departmentId', description: 'Department ID' })
  @ApiQuery({
    name: 'create',
    required: false,
    description: 'Create meeting if not exists',
    type: Boolean,
  })
  @ApiResponse({ status: 200, description: 'Today\'s meeting' })
  @ApiResponse({ status: 404, description: 'No meeting found for today' })
  getTodaysMeeting(
    @Param('departmentId') departmentId: string,
    @Query('create') create?: string,
  ) {
    const createIfNotExists = create === 'true';
    return this.meetingService.getTodaysMeeting(departmentId, createIfNotExists);
  }

  @Get('history/:departmentId')
  @RequirePermissions(Permission.MEETING_VIEW)
  @ApiOperation({ summary: 'Get meeting history for a department' })
  @ApiParam({ name: 'departmentId', description: 'Department ID' })
  @ApiQuery({
    name: 'days',
    required: false,
    description: 'Number of days to look back (default: 30)',
    type: Number,
  })
  @ApiResponse({ status: 200, description: 'Meeting history' })
  getMeetingHistory(
    @Param('departmentId') departmentId: string,
    @Query('days') days?: string,
  ) {
    return this.meetingService.getMeetingHistory(
      departmentId,
      days ? parseInt(days, 10) : 30,
    );
  }

  @Get('kpi-trends/:departmentId')
  @RequirePermissions(Permission.MEETING_VIEW)
  @ApiOperation({ summary: 'Get KPI trends over time for a department' })
  @ApiParam({ name: 'departmentId', description: 'Department ID' })
  @ApiQuery({
    name: 'category',
    required: false,
    enum: SQCDMCategory,
    description: 'Filter by SQCDM category',
  })
  @ApiQuery({
    name: 'days',
    required: false,
    description: 'Number of days to analyze (default: 30)',
    type: Number,
  })
  @ApiResponse({ status: 200, description: 'KPI trend data' })
  getKpiTrends(
    @Param('departmentId') departmentId: string,
    @Query('category') category?: SQCDMCategory,
    @Query('days') days?: string,
  ) {
    return this.meetingService.getKpiTrends(
      departmentId,
      category,
      days ? parseInt(days, 10) : 30,
    );
  }

  @Get(':id')
  @RequirePermissions(Permission.MEETING_VIEW)
  @ApiOperation({ summary: 'Get a meeting by ID' })
  @ApiParam({ name: 'id', description: 'Meeting ID' })
  @ApiResponse({ status: 200, description: 'Meeting details' })
  @ApiResponse({ status: 404, description: 'Meeting not found' })
  findMeetingById(@Param('id') id: string) {
    return this.meetingService.findMeetingById(id);
  }

  @Put(':id')
  @RequirePermissions(Permission.MEETING_UPDATE)
  @AuditLog('MorningMeeting', 'UPDATE')
  @ApiOperation({ summary: 'Update a meeting' })
  @ApiParam({ name: 'id', description: 'Meeting ID' })
  @ApiResponse({ status: 200, description: 'Meeting updated' })
  @ApiResponse({ status: 404, description: 'Meeting not found' })
  updateMeeting(@Param('id') id: string, @Body() updateDto: UpdateMeetingDto) {
    return this.meetingService.updateMeeting(id, updateDto);
  }

  @Delete(':id')
  @RequirePermissions(Permission.MEETING_DELETE)
  @AuditLog('MorningMeeting', 'DELETE')
  @HttpCode(HttpStatus.OK)
  @ApiOperation({ summary: 'Delete a meeting' })
  @ApiParam({ name: 'id', description: 'Meeting ID' })
  @ApiResponse({ status: 200, description: 'Meeting deleted' })
  @ApiResponse({ status: 404, description: 'Meeting not found' })
  deleteMeeting(@Param('id') id: string) {
    return this.meetingService.deleteMeeting(id);
  }

  @Post(':id/start')
  @RequirePermissions(Permission.MEETING_UPDATE)
  @AuditLog('MorningMeeting', 'START')
  @ApiOperation({ summary: 'Start a meeting (begin timer)' })
  @ApiParam({ name: 'id', description: 'Meeting ID' })
  @ApiResponse({ status: 200, description: 'Meeting started' })
  @ApiResponse({ status: 400, description: 'Meeting cannot be started' })
  @ApiResponse({ status: 404, description: 'Meeting not found' })
  startMeeting(@Param('id') id: string) {
    return this.meetingService.startMeeting(id);
  }

  @Post(':id/end')
  @RequirePermissions(Permission.MEETING_UPDATE)
  @AuditLog('MorningMeeting', 'END')
  @ApiOperation({ summary: 'End a meeting (stop timer)' })
  @ApiParam({ name: 'id', description: 'Meeting ID' })
  @ApiResponse({ status: 200, description: 'Meeting ended' })
  @ApiResponse({ status: 400, description: 'Meeting cannot be ended' })
  @ApiResponse({ status: 404, description: 'Meeting not found' })
  endMeeting(@Param('id') id: string) {
    return this.meetingService.endMeeting(id);
  }

  // ============================================================================
  // TOPIC ENDPOINTS
  // ============================================================================

  @Post(':id/topics')
  @RequirePermissions(Permission.MEETING_CREATE)
  @AuditLog('MorningMeetingTopic', 'CREATE')
  @ApiOperation({ summary: 'Add a topic to a meeting' })
  @ApiParam({ name: 'id', description: 'Meeting ID' })
  @ApiResponse({ status: 201, description: 'Topic added' })
  @ApiResponse({ status: 404, description: 'Meeting not found' })
  addTopic(@Param('id') id: string, @Body() createDto: CreateTopicDto) {
    return this.meetingService.addTopic(id, createDto);
  }

  @Put('topics/:id')
  @RequirePermissions(Permission.MEETING_UPDATE)
  @AuditLog('MorningMeetingTopic', 'UPDATE')
  @ApiOperation({ summary: 'Update a topic' })
  @ApiParam({ name: 'id', description: 'Topic ID' })
  @ApiResponse({ status: 200, description: 'Topic updated' })
  @ApiResponse({ status: 404, description: 'Topic not found' })
  updateTopic(@Param('id') id: string, @Body() updateDto: UpdateTopicDto) {
    return this.meetingService.updateTopic(id, updateDto);
  }

  @Delete('topics/:id')
  @RequirePermissions(Permission.MEETING_DELETE)
  @AuditLog('MorningMeetingTopic', 'DELETE')
  @HttpCode(HttpStatus.OK)
  @ApiOperation({ summary: 'Delete a topic' })
  @ApiParam({ name: 'id', description: 'Topic ID' })
  @ApiResponse({ status: 200, description: 'Topic deleted' })
  @ApiResponse({ status: 404, description: 'Topic not found' })
  deleteTopic(@Param('id') id: string) {
    return this.meetingService.deleteTopic(id);
  }

  // ============================================================================
  // ACTION ENDPOINTS
  // ============================================================================

  @Post(':id/actions')
  @RequirePermissions(Permission.MEETING_CREATE)
  @AuditLog('MorningMeetingAction', 'CREATE')
  @ApiOperation({ summary: 'Add an action item to a meeting' })
  @ApiParam({ name: 'id', description: 'Meeting ID' })
  @ApiResponse({ status: 201, description: 'Action added' })
  @ApiResponse({ status: 404, description: 'Meeting not found' })
  addAction(@Param('id') id: string, @Body() createDto: CreateActionDto) {
    return this.meetingService.addAction(id, createDto);
  }

  @Put('actions/:id')
  @RequirePermissions(Permission.MEETING_UPDATE)
  @AuditLog('MorningMeetingAction', 'UPDATE')
  @ApiOperation({ summary: 'Update an action item' })
  @ApiParam({ name: 'id', description: 'Action ID' })
  @ApiResponse({ status: 200, description: 'Action updated' })
  @ApiResponse({ status: 404, description: 'Action not found' })
  updateAction(@Param('id') id: string, @Body() updateDto: UpdateActionDto) {
    return this.meetingService.updateAction(id, updateDto);
  }

  @Put('actions/:id/complete')
  @RequirePermissions(Permission.MEETING_UPDATE)
  @AuditLog('MorningMeetingAction', 'COMPLETE')
  @ApiOperation({ summary: 'Mark an action item as completed' })
  @ApiParam({ name: 'id', description: 'Action ID' })
  @ApiResponse({ status: 200, description: 'Action completed' })
  @ApiResponse({ status: 400, description: 'Action already completed' })
  @ApiResponse({ status: 404, description: 'Action not found' })
  completeAction(@Param('id') id: string) {
    return this.meetingService.completeAction(id);
  }
}
