import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import {
  IsOptional,
  IsString,
  IsBoolean,
  IsArray,
  IsEnum,
  IsInt,
  IsNotEmpty,
  Min,
  Max,
} from 'class-validator';
import { Type, Transform } from 'class-transformer';

// ============================================================================
// Request DTOs
// ============================================================================

export class GetTasksQueryDto {
  @ApiPropertyOptional({ description: 'Filter by project ID' })
  @IsOptional()
  @IsString()
  projectId?: string;

  @ApiPropertyOptional({ description: 'Filter by section ID' })
  @IsOptional()
  @IsString()
  sectionId?: string;

  @ApiPropertyOptional({ description: 'Filter by label name' })
  @IsOptional()
  @IsString()
  label?: string;

  @ApiPropertyOptional({
    description: 'Filter expression (e.g., "today", "overdue", "p1")',
    example: 'today',
  })
  @IsOptional()
  @IsString()
  filter?: string;
}

export class CreateTaskDto {
  @ApiProperty({ description: 'Task content/title', example: 'Buy groceries' })
  @IsString()
  @IsNotEmpty()
  content: string;

  @ApiPropertyOptional({
    description: 'Task description',
    example: 'Milk, eggs, bread',
  })
  @IsOptional()
  @IsString()
  description?: string;

  @ApiPropertyOptional({ description: 'Project ID' })
  @IsOptional()
  @IsString()
  projectId?: string;

  @ApiPropertyOptional({ description: 'Section ID' })
  @IsOptional()
  @IsString()
  sectionId?: string;

  @ApiPropertyOptional({ description: 'Parent task ID (for subtasks)' })
  @IsOptional()
  @IsString()
  parentId?: string;

  @ApiPropertyOptional({
    description: 'Labels',
    example: ['work', 'urgent'],
    type: [String],
  })
  @IsOptional()
  @IsArray()
  @IsString({ each: true })
  labels?: string[];

  @ApiPropertyOptional({
    description: 'Priority (1=normal, 4=urgent)',
    minimum: 1,
    maximum: 4,
    default: 1,
  })
  @IsOptional()
  @IsInt()
  @Min(1)
  @Max(4)
  @Type(() => Number)
  priority?: 1 | 2 | 3 | 4;

  @ApiPropertyOptional({
    description: 'Due date string (e.g., "tomorrow", "next Monday")',
    example: 'tomorrow at 10am',
  })
  @IsOptional()
  @IsString()
  dueString?: string;

  @ApiPropertyOptional({
    description: 'Due date (YYYY-MM-DD)',
    example: '2024-12-31',
  })
  @IsOptional()
  @IsString()
  dueDate?: string;

  @ApiPropertyOptional({ description: 'Assignee ID' })
  @IsOptional()
  @IsString()
  assigneeId?: string;

  @ApiPropertyOptional({ description: 'Duration in minutes', example: 60 })
  @IsOptional()
  @IsInt()
  @Min(1)
  @Type(() => Number)
  duration?: number;

  @ApiPropertyOptional({
    description: 'Duration unit',
    enum: ['minute', 'day'],
    default: 'minute',
  })
  @IsOptional()
  @IsEnum(['minute', 'day'])
  durationUnit?: 'minute' | 'day';
}

export class UpdateTaskDto {
  @ApiPropertyOptional({ description: 'Task content/title' })
  @IsOptional()
  @IsString()
  content?: string;

  @ApiPropertyOptional({ description: 'Task description' })
  @IsOptional()
  @IsString()
  description?: string;

  @ApiPropertyOptional({ description: 'Labels', type: [String] })
  @IsOptional()
  @IsArray()
  @IsString({ each: true })
  labels?: string[];

  @ApiPropertyOptional({
    description: 'Priority (1=normal, 4=urgent)',
    minimum: 1,
    maximum: 4,
  })
  @IsOptional()
  @IsInt()
  @Min(1)
  @Max(4)
  @Type(() => Number)
  priority?: 1 | 2 | 3 | 4;

  @ApiPropertyOptional({ description: 'Due date string' })
  @IsOptional()
  @IsString()
  dueString?: string;

  @ApiPropertyOptional({ description: 'Due date (YYYY-MM-DD)' })
  @IsOptional()
  @IsString()
  dueDate?: string;

  @ApiPropertyOptional({ description: 'Assignee ID (null to unassign)' })
  @IsOptional()
  @IsString()
  assigneeId?: string | null;
}

export class CreateProjectDto {
  @ApiProperty({ description: 'Project name', example: 'My Project' })
  @IsString()
  @IsNotEmpty()
  name: string;

  @ApiPropertyOptional({ description: 'Parent project ID' })
  @IsOptional()
  @IsString()
  parentId?: string;

  @ApiPropertyOptional({
    description: 'Project color',
    example: 'blue',
  })
  @IsOptional()
  @IsString()
  color?: string;

  @ApiPropertyOptional({ description: 'Mark as favorite', default: false })
  @IsOptional()
  @IsBoolean()
  @Transform(({ value }) => value === 'true' || value === true)
  isFavorite?: boolean;

  @ApiPropertyOptional({
    description: 'View style',
    enum: ['list', 'board'],
    default: 'list',
  })
  @IsOptional()
  @IsEnum(['list', 'board'])
  viewStyle?: 'list' | 'board';
}

export class UpdateProjectDto {
  @ApiPropertyOptional({ description: 'Project name' })
  @IsOptional()
  @IsString()
  name?: string;

  @ApiPropertyOptional({ description: 'Project color' })
  @IsOptional()
  @IsString()
  color?: string;

  @ApiPropertyOptional({ description: 'Mark as favorite' })
  @IsOptional()
  @IsBoolean()
  @Transform(({ value }) => value === 'true' || value === true)
  isFavorite?: boolean;

  @ApiPropertyOptional({
    description: 'View style',
    enum: ['list', 'board'],
  })
  @IsOptional()
  @IsEnum(['list', 'board'])
  viewStyle?: 'list' | 'board';
}

// ============================================================================
// Response DTOs
// ============================================================================

export class DueResponseDto {
  @ApiProperty({ example: '2024-12-31' })
  date: string;

  @ApiProperty({ example: 'Dec 31' })
  string: string;

  @ApiProperty({ example: false })
  isRecurring: boolean;

  @ApiPropertyOptional({ example: '2024-12-31T10:00:00Z' })
  datetime?: string;
}

export class TaskResponseDto {
  @ApiProperty()
  id: string;

  @ApiProperty()
  content: string;

  @ApiProperty()
  description: string;

  @ApiProperty()
  projectId: string;

  @ApiPropertyOptional()
  sectionId?: string;

  @ApiPropertyOptional()
  parentId?: string;

  @ApiProperty()
  isCompleted: boolean;

  @ApiProperty({ type: [String] })
  labels: string[];

  @ApiProperty({ minimum: 1, maximum: 4 })
  priority: number;

  @ApiProperty()
  commentCount: number;

  @ApiProperty()
  createdAt: string;

  @ApiPropertyOptional({ type: DueResponseDto })
  due?: DueResponseDto;

  @ApiProperty()
  url: string;
}

export class ProjectResponseDto {
  @ApiProperty()
  id: string;

  @ApiProperty()
  name: string;

  @ApiProperty()
  color: string;

  @ApiPropertyOptional()
  parentId?: string;

  @ApiProperty()
  order: number;

  @ApiProperty()
  commentCount: number;

  @ApiProperty()
  isShared: boolean;

  @ApiProperty()
  isFavorite: boolean;

  @ApiProperty()
  isInboxProject: boolean;

  @ApiProperty({ enum: ['list', 'board'] })
  viewStyle: string;

  @ApiProperty()
  url: string;
}

export class SectionResponseDto {
  @ApiProperty()
  id: string;

  @ApiProperty()
  projectId: string;

  @ApiProperty()
  name: string;

  @ApiProperty()
  order: number;
}

export class LabelResponseDto {
  @ApiProperty()
  id: string;

  @ApiProperty()
  name: string;

  @ApiProperty()
  color: string;

  @ApiProperty()
  order: number;

  @ApiProperty()
  isFavorite: boolean;
}
