import { isDateInPast, TeamMember } from '.'

export {}

export enum TaskStatus {
  Todo = 'todo',
  InProgress = 'in_progress',
  Done = 'done',
}

export enum TaskPriority {
  Low = 'Low',
  Medium = 'Medium',
  High = 'High',
}

export type Task = {
  id: number
  name: string
  detail?: string
  projectId?: number
  teamId?: number
  priority?: TaskPriority
  dueDate: Date
  assignees: TeamMember[]
  completed: boolean
}

export type RepeatableTask = {
  id: number
  name: string
  detail?: string
  projectId?: number
  teamId?: number
  priority?: TaskPriority
  assignees: TeamMember[]
  completed?: boolean

  period: 'Daily' | 'Weekly' | 'Monthly' | 'Annually'
  rate: number[]
  hourlyDueDuration: number
  next: Date
  endDate?: Date
}

export const isTaskValid = (task: Task): boolean => {
  return task.name.length > 0
}

export const isRepeatableTaskValid = (task: RepeatableTask): boolean => {
  return (
    task.name.length > 0 &&
    task.period !== undefined &&
    task.rate !== undefined &&
    task.assignees.length > 0
  )
}

export type Project = {
  id: number
  title: string
  brief: string
  completed: boolean
  dueDate: Date
  members: TeamMember[]
  // TODO: Add Type when we have it
  repeatableTasks: any[]
  tasks: Task[]
  progress: number
  // TODO: Add Team Type when we have it
  team: any
}

export const taskIncludesUser = (
  task: { assignees: TeamMember[] },
  userId: number,
) => {
  return task.assignees.some((a: TeamMember) => a.userId === userId)
}

export type TaskCreationFormType = {
  name: string
  detail?: string
  dueDate?: Date
  // Ids of team members assigned to this task
  assignees: number[]
  priority?: TaskPriority
  projectId?: number

  // Only for repeatable tasks
  // required
  period?: 'Daily' | 'Weekly' | 'Monthly' | 'Annually'
  // required
  rate: number[]
  // required (>=0)
  hourlyDueDuration?: number
  start?: Date
  // end must be after start
  end?: Date
}

export const isTaskCreationFormValid = (
  form: TaskCreationFormType,
  repeatable = false,
): boolean => {
  if (!repeatable) {
    return form.name?.length > 0 && !isDateInPast(form.dueDate)
  }

  if (!form.period) return false
  let isRateValid = false
  switch (form.period) {
    case 'Daily':
      isRateValid = form.rate?.length <= 0
      break
    case 'Weekly':
      isRateValid = form.rate?.length >= 7
      break
    case 'Monthly':
      isRateValid = form.rate?.length >= 1
      break
    case 'Annually':
      isRateValid = form.rate?.length >= 2
  }
  if (!isRateValid) return false

  if (form.start && form.end) {
    if (!(form.start.getTime() < form.end.getTime())) {
      return false
    }
  }

  return (
    form.name?.length > 0 &&
    !isDateInPast(form.start) &&
    !isDateInPast(form.end)
  )
}

export type TaskUpdateFormType = {
  name?: string
  status?: TaskStatus
}

export const getTaskStatusColor = (status: TaskStatus): string => {
  switch (status) {
    case TaskStatus.Todo:
      return 'bg-red-500'
    case TaskStatus.InProgress:
      return 'bg-yellow-500'
    case TaskStatus.Done:
      return 'bg-green-500'
  }
}

export const getTaskStatusIcon = (status: TaskStatus): string => {
  switch (status) {
    case TaskStatus.Todo:
      return 'exclamation'
    case TaskStatus.InProgress:
      return 'clock'
    case TaskStatus.Done:
      return 'check'
  }
}

export const getTaskStatusName = (status: TaskStatus): string => {
  switch (status) {
    case TaskStatus.Todo:
      return 'To do'
    case TaskStatus.InProgress:
      return 'In progress'
    case TaskStatus.Done:
      return 'Done'
  }
}

export const getTaskStatuses = (): TaskStatus[] => {
  return [TaskStatus.Todo, TaskStatus.InProgress, TaskStatus.Done]
}

export const getTaskStatusesExcept = (status: TaskStatus): TaskStatus[] => {
  return getTaskStatuses().filter(s => s !== status)
}

// REST Endpoints

/**
 * Endpoint to get all tasks
 * @method GET
 * @returns {Task[]} Tasks - Array of tasks
 */
export const GET_ALL_TASKS_ENDPOINT = '/dashboard/api/v1/projects/tasks'

/**
 * Endpoint to create a new task
 * @method POST
 * @returns {Task} Task - Task object
 * @body {TaskCreationFormType} TaskCreationFormType - Task creation form
 */
export const CREATE_TASK_ENDPOINT = '/dashboard/api/v1/projects/task'

/**
 * Endpoint to create a new repeatable task
 * @method POST
 * @returns {Task} Task - Task object
 * @body {TaskCreationFormType} TaskCreationFormType - Task creation form
 */
export const CREATE_REPEATABLE_TASK_ENDPOINT =
  '/dashboard/api/v1/projects/task/repeatable'

/**
 * Endpoint to get a single task
 * @method GET
 * @param taskId ID of the task
 * @body {TaskCreationFormType} TaskCreationFormType - Task creation form
 * @returns {Task} Task - Task object
 */
export const GET_SINGLE_TASK_ENDPOINT = (taskId: number): string =>
  `/dashboard/api/v1/projects/task/${taskId}`

/**
 * Endpoint to get a single repeatable task
 * @method GET
 * @param taskId ID of the task
 * @returns {RepeatableTask} Task - Task object
 */
export const GET_SINGLE_REPEATABLE_TASK_ENDPOINT = (taskId: number): string =>
  `/dashboard/api/v1/projects/task/repeatable/${taskId}`

/**
 * Endpoint to update a task
 * @method PUT
 * @param taskId ID of the task
 * @body {TaskUpdateFormType} TaskUpdateFormType - Task update form
 * @returns {Task} Task - Task object
 */
export const UPDATE_TASK_ENDPOINT = (taskId: number): string =>
  `/dashboard/api/v1/projects/task/${taskId}`

/**
 * Endpoint to update a task
 * @method PUT
 * @param taskId ID of the task
 * @body {RepeatableTaskUpdateFormType} TaskUpdateFormType - Task update form
 * @returns {RepeatableTask} Task - Task object
 */
export const UPDATE_REPEATABLE_TASK_ENDPOINT = (taskId: number): string =>
  `/dashboard/api/v1/projects/task/repeatable/${taskId}`

/**
 * Endpoint to delete a task
 * @method DELETE
 * @param taskId ID of the task
 * @returns {Task} Task - Task object
 */
export const DELETE_TASK_ENDPOINT = (taskId: number): string =>
  `/dashboard/api/v1/projects/task/${taskId}`

/**
 * Endpoint to get all projects
 * @method GET
 * @returns {Project[]} Projects - Array of projects
 */
export const GET_ALL_PROJECTS_ENDPOINT = '/dashboard/api/v1/projects'

/**
 * Endpoint to get a single project
 * @method GET
 * @param projectId ID of the project
 * @returns {Project} Project - Project object
 */
export const GET_SINGLE_PROJECT_ENDPOINT = (projectId: number): string =>
  `/dashboard/api/v1/project/${projectId}`

/**
 * Endpoint to duplicate a project
 * @method POST
 * @BODY {projectId: number, title: string} - Project ID and new title
 * @returns {Project} Project - Project object
 */
export const DUPLICATE_PROJECT_ENDPOINT = '/dashboard/api/v1/project/duplicate'

/**
 * Endpoint to create a new project
 * @method POST
 * @body Project form with title, brief, due date, assignees
 * @returns {Project} Project - Project object
 */
export const CREATE_PROJECT_ENDPOINT = '/dashboard/api/v1/project'

export const REMOVE_MEMBER_FROM_PROJECT_ENDPOINT = (
  projectId: number,
  memberId: number,
): string => `/dashboard/api/v1/project/${projectId}/member/${memberId}`

/**
 * Endpoint to update a project
 * @method PUT
 * @param projectId ID of the project
 * @body {Project} Project - Project object
 * @returns {Project} Project - Project object
 */
export const UPDATE_PROJECT_ENDPOINT = (projectId: number): string =>
  `/dashboard/api/v1/project/${projectId}`

declare global {}
