import { Request, Response } from 'express';
import { TaskService } from '../services/task.service';
import { 
  CreateTask,
  UpdateTask,
  TaskQuery,
  BulkCreateTasks,
  BulkUpdateTasks,
  BulkDeleteTasks,
  DuplicateTask,
  CreateTemplateFromTask,
  ApplyTemplate
} from '../validators/task.validator';

export class TaskController {
  private taskService: TaskService;

  constructor() {
    this.taskService = new TaskService();
  }

  /**
   * Create a new task
   */
  async createTask(req: Request<{}, {}, CreateTask>, res: Response) {
    try {
      const task = await this.taskService.createTask(req.body);
      
      res.status(201).json({
        success: true,
        data: task,
        message: 'Task created successfully'
      });
    } catch (error: any) {
      res.status(500).json({
        success: false,
        error: error.message || 'Failed to create task'
      });
    }
  }

  /**
   * Get all tasks with pagination
   */
  async getTasks(req: Request<{}, {}, {}, TaskQuery>, res: Response) {
    try {
      const result = await this.taskService.getTasks(req.query);
      
      res.json({
        success: true,
        ...result
      });
    } catch (error: any) {
      res.status(500).json({
        success: false,
        error: error.message || 'Failed to fetch tasks'
      });
    }
  }

  /**
   * Get a single task by ID
   */
  async getTaskById(req: Request<{ id: string }>, res: Response) {
    try {
      const task = await this.taskService.getTaskById(req.params.id);
      
      res.json({
        success: true,
        data: task
      });
    } catch (error: any) {
      const statusCode = error.message === 'Task not found' ? 404 : 500;
      res.status(statusCode).json({
        success: false,
        error: error.message || 'Failed to fetch task'
      });
    }
  }

  /**
   * Update a task
   */
  async updateTask(req: Request<{ id: string }, {}, UpdateTask>, res: Response) {
    try {
      const task = await this.taskService.updateTask(req.params.id, req.body);
      
      res.json({
        success: true,
        data: task,
        message: 'Task updated successfully'
      });
    } catch (error: any) {
      res.status(500).json({
        success: false,
        error: error.message || 'Failed to update task'
      });
    }
  }

  /**
   * Delete a task
   */
  async deleteTask(req: Request<{ id: string }>, res: Response) {
    try {
      await this.taskService.deleteTask(req.params.id);
      
      res.json({
        success: true,
        message: 'Task deleted successfully'
      });
    } catch (error: any) {
      res.status(500).json({
        success: false,
        error: error.message || 'Failed to delete task'
      });
    }
  }

  /**
   * Bulk create tasks
   */
  async bulkCreateTasks(req: Request<{}, {}, BulkCreateTasks>, res: Response) {
    try {
      const tasks = await this.taskService.bulkCreateTasks(req.body);
      
      res.status(201).json({
        success: true,
        data: tasks,
        message: `${tasks.length} tasks created successfully`
      });
    } catch (error: any) {
      res.status(500).json({
        success: false,
        error: error.message || 'Failed to bulk create tasks'
      });
    }
  }

  /**
   * Bulk update tasks
   */
  async bulkUpdateTasks(req: Request<{}, {}, BulkUpdateTasks>, res: Response) {
    try {
      const tasks = await this.taskService.bulkUpdateTasks(req.body);
      
      res.json({
        success: true,
        data: tasks,
        message: `${tasks.length} tasks updated successfully`
      });
    } catch (error: any) {
      res.status(500).json({
        success: false,
        error: error.message || 'Failed to bulk update tasks'
      });
    }
  }

  /**
   * Bulk delete tasks
   */
  async bulkDeleteTasks(req: Request<{}, {}, BulkDeleteTasks>, res: Response) {
    try {
      await this.taskService.bulkDeleteTasks(req.body);
      
      res.json({
        success: true,
        message: `${req.body.ids.length} tasks deleted successfully`
      });
    } catch (error: any) {
      res.status(500).json({
        success: false,
        error: error.message || 'Failed to bulk delete tasks'
      });
    }
  }

  /**
   * Duplicate a task
   */
  async duplicateTask(req: Request<{}, {}, DuplicateTask>, res: Response) {
    try {
      const task = await this.taskService.duplicateTask(req.body);
      
      res.status(201).json({
        success: true,
        data: task,
        message: 'Task duplicated successfully'
      });
    } catch (error: any) {
      res.status(500).json({
        success: false,
        error: error.message || 'Failed to duplicate task'
      });
    }
  }

  /**
   * Create a template from a task
   */
  async createTemplateFromTask(req: Request<{}, {}, CreateTemplateFromTask>, res: Response) {
    try {
      const template = await this.taskService.createTemplateFromTask(req.body);
      
      res.status(201).json({
        success: true,
        data: template,
        message: 'Template created successfully from task'
      });
    } catch (error: any) {
      res.status(500).json({
        success: false,
        error: error.message || 'Failed to create template from task'
      });
    }
  }

  /**
   * Apply a template to create a new task
   */
  async applyTemplate(req: Request<{}, {}, ApplyTemplate>, res: Response) {
    try {
      const task = await this.taskService.applyTemplate(req.body);
      
      res.status(201).json({
        success: true,
        data: task,
        message: 'Task created successfully from template'
      });
    } catch (error: any) {
      res.status(500).json({
        success: false,
        error: error.message || 'Failed to apply template'
      });
    }
  }
}