import {
  CreateTaskSchema,
  UpdateTaskSchema,
  TaskQuerySchema,
  BulkCreateTasksSchema,
  BulkUpdateTasksSchema,
  BulkDeleteTasksSchema,
  DuplicateTaskSchema,
  CreateTemplateFromTaskSchema,
  ApplyTemplateSchema
} from '../../src/api/validators/task.validator';

describe('Task Validators', () => {
  describe('CreateTaskSchema', () => {
    it('should validate a valid task creation request', () => {
      const validTask = {
        title: 'Test Task',
        description: 'Test Description',
        priority: 'medium',
        task_type: 'feature',
        project: '123e4567-e89b-12d3-a456-426614174000'
      };

      const result = CreateTaskSchema.safeParse(validTask);
      expect(result.success).toBe(true);
      if (result.success) {
        expect(result.data.title).toBe('Test Task');
        expect(result.data.priority).toBe('medium');
      }
    });

    it('should reject invalid task creation request', () => {
      const invalidTask = {
        // Missing required title
        description: 'Test Description',
        priority: 'invalid-priority', // Invalid enum value
        project: 'not-a-uuid' // Invalid UUID
      };

      const result = CreateTaskSchema.safeParse(invalidTask);
      expect(result.success).toBe(false);
      if (!result.success) {
        expect(result.error.errors).toHaveLength(3);
      }
    });

    it('should apply default values', () => {
      const taskWithDefaults = {
        title: 'Test Task',
        project: '123e4567-e89b-12d3-a456-426614174000'
      };

      const result = CreateTaskSchema.safeParse(taskWithDefaults);
      expect(result.success).toBe(true);
      if (result.success) {
        expect(result.data.priority).toBe('medium');
        expect(result.data.progress_percentage).toBe(0);
        expect(result.data.ai_generated).toBe(false);
        expect(result.data.auto_status_updates).toBe(false);
      }
    });
  });

  describe('UpdateTaskSchema', () => {
    it('should validate partial update', () => {
      const partialUpdate = {
        title: 'Updated Title',
        priority: 'high'
      };

      const result = UpdateTaskSchema.safeParse(partialUpdate);
      expect(result.success).toBe(true);
      if (result.success) {
        expect(result.data.title).toBe('Updated Title');
        expect(result.data.priority).toBe('high');
      }
    });

    it('should accept empty update', () => {
      const emptyUpdate = {};

      const result = UpdateTaskSchema.safeParse(emptyUpdate);
      expect(result.success).toBe(true);
    });
  });

  describe('TaskQuerySchema', () => {
    it('should validate query parameters', () => {
      const validQuery = {
        page: '2',
        limit: '50',
        sort: 'created_at,-priority',
        search: 'test query'
      };

      const result = TaskQuerySchema.safeParse(validQuery);
      expect(result.success).toBe(true);
      if (result.success) {
        expect(result.data.page).toBe(2);
        expect(result.data.limit).toBe(50);
        expect(result.data.sort).toBe('created_at,-priority');
      }
    });

    it('should apply default pagination values', () => {
      const emptyQuery = {};

      const result = TaskQuerySchema.safeParse(emptyQuery);
      expect(result.success).toBe(true);
      if (result.success) {
        expect(result.data.page).toBe(1);
        expect(result.data.limit).toBe(20);
      }
    });

    it('should reject invalid pagination values', () => {
      const invalidQuery = {
        page: '0', // Must be positive
        limit: '200' // Exceeds max limit of 100
      };

      const result = TaskQuerySchema.safeParse(invalidQuery);
      expect(result.success).toBe(false);
    });
  });

  describe('BulkCreateTasksSchema', () => {
    it('should validate bulk create request', () => {
      const bulkCreate = {
        tasks: [
          {
            title: 'Task 1',
            project: '123e4567-e89b-12d3-a456-426614174000'
          },
          {
            title: 'Task 2',
            project: '123e4567-e89b-12d3-a456-426614174000'
          }
        ]
      };

      const result = BulkCreateTasksSchema.safeParse(bulkCreate);
      expect(result.success).toBe(true);
      if (result.success) {
        expect(result.data.tasks).toHaveLength(2);
      }
    });

    it('should reject empty tasks array', () => {
      const emptyBulk = {
        tasks: []
      };

      const result = BulkCreateTasksSchema.safeParse(emptyBulk);
      expect(result.success).toBe(false);
    });

    it('should reject more than 100 tasks', () => {
      const tooManyTasks = {
        tasks: Array(101).fill({
          title: 'Task',
          project: '123e4567-e89b-12d3-a456-426614174000'
        })
      };

      const result = BulkCreateTasksSchema.safeParse(tooManyTasks);
      expect(result.success).toBe(false);
    });
  });

  describe('BulkUpdateTasksSchema', () => {
    it('should validate bulk update request', () => {
      const bulkUpdate = {
        ids: [
          '123e4567-e89b-12d3-a456-426614174000',
          '123e4567-e89b-12d3-a456-426614174001'
        ],
        updates: {
          priority: 'high',
          status: '123e4567-e89b-12d3-a456-426614174002'
        }
      };

      const result = BulkUpdateTasksSchema.safeParse(bulkUpdate);
      expect(result.success).toBe(true);
    });
  });

  describe('BulkDeleteTasksSchema', () => {
    it('should validate bulk delete request', () => {
      const bulkDelete = {
        ids: [
          '123e4567-e89b-12d3-a456-426614174000',
          '123e4567-e89b-12d3-a456-426614174001'
        ]
      };

      const result = BulkDeleteTasksSchema.safeParse(bulkDelete);
      expect(result.success).toBe(true);
    });

    it('should reject invalid UUIDs', () => {
      const invalidDelete = {
        ids: ['not-a-uuid', 'another-invalid-id']
      };

      const result = BulkDeleteTasksSchema.safeParse(invalidDelete);
      expect(result.success).toBe(false);
    });
  });

  describe('DuplicateTaskSchema', () => {
    it('should validate duplicate task request', () => {
      const duplicateRequest = {
        taskId: '123e4567-e89b-12d3-a456-426614174000',
        includeSubtasks: true,
        includeAttachments: false,
        overrides: {
          title: 'Duplicated Task'
        }
      };

      const result = DuplicateTaskSchema.safeParse(duplicateRequest);
      expect(result.success).toBe(true);
      if (result.success) {
        expect(result.data.includeSubtasks).toBe(true);
        expect(result.data.includeAttachments).toBe(false);
        expect(result.data.includeComments).toBe(false); // Default value
      }
    });
  });

  describe('CreateTemplateFromTaskSchema', () => {
    it('should validate template creation request', () => {
      const templateRequest = {
        taskId: '123e4567-e89b-12d3-a456-426614174000',
        templateName: 'Feature Template',
        templateDescription: 'Template for new features',
        excludeFields: ['notes', 'created_by']
      };

      const result = CreateTemplateFromTaskSchema.safeParse(templateRequest);
      expect(result.success).toBe(true);
    });

    it('should require template name', () => {
      const invalidRequest = {
        taskId: '123e4567-e89b-12d3-a456-426614174000'
        // Missing templateName
      };

      const result = CreateTemplateFromTaskSchema.safeParse(invalidRequest);
      expect(result.success).toBe(false);
    });
  });

  describe('ApplyTemplateSchema', () => {
    it('should validate template application request', () => {
      const applyRequest = {
        templateId: '123e4567-e89b-12d3-a456-426614174000',
        projectId: '123e4567-e89b-12d3-a456-426614174001',
        overrides: {
          title: 'Custom Title from Template'
        }
      };

      const result = ApplyTemplateSchema.safeParse(applyRequest);
      expect(result.success).toBe(true);
    });
  });
});