import {
  Controller,
  Get,
  Post,
  Put,
  Delete,
  Body,
  Param,
  Query,
  HttpCode,
  HttpStatus,
} from '@nestjs/common';
import {
  ApiTags,
  ApiOperation,
  ApiResponse,
  ApiBearerAuth,
  ApiParam,
} from '@nestjs/swagger';
import { TodoistService } from './todoist.service';
import {
  GetTasksQueryDto,
  CreateTaskDto,
  UpdateTaskDto,
  CreateProjectDto,
  UpdateProjectDto,
  TaskResponseDto,
  ProjectResponseDto,
  SectionResponseDto,
  LabelResponseDto,
} from './dto';
import { ConnectionTestResult } from '../base-connector';
import { RequirePermissions } from '../../../../auth/permissions/permissions.decorator';
import { Permission } from '../../../../auth/permissions/permissions.enum';

@ApiTags('Integrations - Todoist')
@ApiBearerAuth()
@Controller('integrations/todoist')
export class TodoistController {
  constructor(private readonly todoistService: TodoistService) {}

  @Post('test')
  @HttpCode(HttpStatus.OK)
  @ApiOperation({ summary: 'Test Todoist connection' })
  @ApiResponse({
    status: 200,
    description: 'Connection test result',
  })
  @RequirePermissions(Permission.INTEGRATIONS_MANAGE)
  async testConnection(): Promise<ConnectionTestResult> {
    return this.todoistService.testConnection();
  }

  // ===========================================================================
  // Tasks
  // ===========================================================================

  @Get('tasks')
  @ApiOperation({ summary: 'Get list of tasks' })
  @ApiResponse({
    status: 200,
    description: 'List of tasks',
    type: [TaskResponseDto],
  })
  @RequirePermissions(Permission.INTEGRATIONS_VIEW)
  async getTasks(@Query() query: GetTasksQueryDto): Promise<TaskResponseDto[]> {
    return this.todoistService.getTasks(query);
  }

  @Get('tasks/:id')
  @ApiOperation({ summary: 'Get task by ID' })
  @ApiParam({ name: 'id', description: 'Task ID' })
  @ApiResponse({
    status: 200,
    description: 'Task details',
    type: TaskResponseDto,
  })
  @ApiResponse({ status: 404, description: 'Task not found' })
  @RequirePermissions(Permission.INTEGRATIONS_VIEW)
  async getTask(@Param('id') id: string): Promise<TaskResponseDto> {
    return this.todoistService.getTask(id);
  }

  @Post('tasks')
  @ApiOperation({ summary: 'Create a new task' })
  @ApiResponse({
    status: 201,
    description: 'Task created successfully',
    type: TaskResponseDto,
  })
  @RequirePermissions(Permission.INTEGRATIONS_MANAGE)
  async createTask(@Body() dto: CreateTaskDto): Promise<TaskResponseDto> {
    return this.todoistService.createTask(dto);
  }

  @Put('tasks/:id')
  @ApiOperation({ summary: 'Update a task' })
  @ApiParam({ name: 'id', description: 'Task ID' })
  @ApiResponse({
    status: 200,
    description: 'Task updated successfully',
    type: TaskResponseDto,
  })
  @ApiResponse({ status: 404, description: 'Task not found' })
  @RequirePermissions(Permission.INTEGRATIONS_MANAGE)
  async updateTask(
    @Param('id') id: string,
    @Body() dto: UpdateTaskDto,
  ): Promise<TaskResponseDto> {
    return this.todoistService.updateTask(id, dto);
  }

  @Post('tasks/:id/complete')
  @HttpCode(HttpStatus.OK)
  @ApiOperation({ summary: 'Complete a task' })
  @ApiParam({ name: 'id', description: 'Task ID' })
  @ApiResponse({
    status: 200,
    description: 'Task completed successfully',
  })
  @RequirePermissions(Permission.INTEGRATIONS_MANAGE)
  async completeTask(@Param('id') id: string): Promise<{ success: boolean }> {
    return this.todoistService.completeTask(id);
  }

  @Post('tasks/:id/reopen')
  @HttpCode(HttpStatus.OK)
  @ApiOperation({ summary: 'Reopen a completed task' })
  @ApiParam({ name: 'id', description: 'Task ID' })
  @ApiResponse({
    status: 200,
    description: 'Task reopened successfully',
  })
  @RequirePermissions(Permission.INTEGRATIONS_MANAGE)
  async reopenTask(@Param('id') id: string): Promise<{ success: boolean }> {
    return this.todoistService.reopenTask(id);
  }

  @Delete('tasks/:id')
  @HttpCode(HttpStatus.NO_CONTENT)
  @ApiOperation({ summary: 'Delete a task' })
  @ApiParam({ name: 'id', description: 'Task ID' })
  @ApiResponse({
    status: 204,
    description: 'Task deleted successfully',
  })
  @ApiResponse({ status: 404, description: 'Task not found' })
  @RequirePermissions(Permission.INTEGRATIONS_MANAGE)
  async deleteTask(@Param('id') id: string): Promise<void> {
    await this.todoistService.deleteTask(id);
  }

  // ===========================================================================
  // Projects
  // ===========================================================================

  @Get('projects')
  @ApiOperation({ summary: 'Get all projects' })
  @ApiResponse({
    status: 200,
    description: 'List of projects',
    type: [ProjectResponseDto],
  })
  @RequirePermissions(Permission.INTEGRATIONS_VIEW)
  async getProjects(): Promise<ProjectResponseDto[]> {
    return this.todoistService.getProjects();
  }

  @Get('projects/:id')
  @ApiOperation({ summary: 'Get project by ID' })
  @ApiParam({ name: 'id', description: 'Project ID' })
  @ApiResponse({
    status: 200,
    description: 'Project details',
    type: ProjectResponseDto,
  })
  @ApiResponse({ status: 404, description: 'Project not found' })
  @RequirePermissions(Permission.INTEGRATIONS_VIEW)
  async getProject(@Param('id') id: string): Promise<ProjectResponseDto> {
    return this.todoistService.getProject(id);
  }

  @Post('projects')
  @ApiOperation({ summary: 'Create a new project' })
  @ApiResponse({
    status: 201,
    description: 'Project created successfully',
    type: ProjectResponseDto,
  })
  @RequirePermissions(Permission.INTEGRATIONS_MANAGE)
  async createProject(
    @Body() dto: CreateProjectDto,
  ): Promise<ProjectResponseDto> {
    return this.todoistService.createProject(dto);
  }

  @Put('projects/:id')
  @ApiOperation({ summary: 'Update a project' })
  @ApiParam({ name: 'id', description: 'Project ID' })
  @ApiResponse({
    status: 200,
    description: 'Project updated successfully',
    type: ProjectResponseDto,
  })
  @ApiResponse({ status: 404, description: 'Project not found' })
  @RequirePermissions(Permission.INTEGRATIONS_MANAGE)
  async updateProject(
    @Param('id') id: string,
    @Body() dto: UpdateProjectDto,
  ): Promise<ProjectResponseDto> {
    return this.todoistService.updateProject(id, dto);
  }

  @Delete('projects/:id')
  @HttpCode(HttpStatus.NO_CONTENT)
  @ApiOperation({ summary: 'Delete a project' })
  @ApiParam({ name: 'id', description: 'Project ID' })
  @ApiResponse({
    status: 204,
    description: 'Project deleted successfully',
  })
  @ApiResponse({ status: 404, description: 'Project not found' })
  @RequirePermissions(Permission.INTEGRATIONS_MANAGE)
  async deleteProject(@Param('id') id: string): Promise<void> {
    await this.todoistService.deleteProject(id);
  }

  // ===========================================================================
  // Sections
  // ===========================================================================

  @Get('sections')
  @ApiOperation({ summary: 'Get sections (optionally filtered by project)' })
  @ApiResponse({
    status: 200,
    description: 'List of sections',
    type: [SectionResponseDto],
  })
  @RequirePermissions(Permission.INTEGRATIONS_VIEW)
  async getSections(
    @Query('projectId') projectId?: string,
  ): Promise<SectionResponseDto[]> {
    return this.todoistService.getSections(projectId);
  }

  // ===========================================================================
  // Labels
  // ===========================================================================

  @Get('labels')
  @ApiOperation({ summary: 'Get all labels' })
  @ApiResponse({
    status: 200,
    description: 'List of labels',
    type: [LabelResponseDto],
  })
  @RequirePermissions(Permission.INTEGRATIONS_VIEW)
  async getLabels(): Promise<LabelResponseDto[]> {
    return this.todoistService.getLabels();
  }
}
