import { computed, onMounted, ref, watch } from 'vue'
import { animate } from 'motion'

import { goalApi, type Goal } from '@/api/goal'
import { reminderApi, type Reminder } from '@/api/reminder'
import { scheduleCenterApi, type ScheduleCenterDateResponse, type ScheduleCenterDaySummary } from '@/api/scheduleCenter'
import { taskApi, type Task, type TaskPriority, type TaskStatus } from '@/api/task'
import { todoApi, type Todo } from '@/api/todo'

type TimelineItem =
  | { id: string; type: 'todo'; tone: 'normal' | 'warn' | 'alert'; time: string; label: string; title: string; meta: string; done: boolean; payload: Todo }
  | { id: string; type: 'task'; tone: 'normal' | 'warn' | 'alert'; time: string; label: string; title: string; meta: string; done: boolean; payload: Task }
  | { id: string; type: 'reminder'; tone: 'normal' | 'warn' | 'alert'; time: string; label: string; title: string; meta: string; done: boolean; payload: Reminder }
  | { id: string; type: 'goal'; tone: 'normal' | 'warn' | 'alert'; time: string; label: string; title: string; meta: string; done: boolean; payload: Goal }

export function useScheduleCenterPage() {
  const weekdayLabels = ['MON', 'TUE', 'WED', 'THU', 'FRI', 'SAT', 'SUN']
  const today = new Date()
  const currentMonth = ref(new Date(today.getFullYear(), today.getMonth(), 1))
  const selectedDate = ref(formatDate(today))
  const panelOpen = ref(false)
  const monthSummary = ref<ScheduleCenterDaySummary[]>([])
  const detail = ref<ScheduleCenterDateResponse | null>(null)
  const loadingMonth = ref(false)
  const loadingDetail = ref(false)
  const monthRequestId = ref(0)
  const detailRequestId = ref(0)

  const newTodoTitle = ref('')
  const newTaskTitle = ref('')
  const newTaskPriority = ref<TaskPriority>('medium')
  const newReminderTitle = ref('')
  const newReminderTime = ref('09:00')
  const newGoalTitle = ref('')
  const panelMode = ref<'detail' | 'create'>('detail')
  const panelAnimation = ref<ReturnType<typeof animate> | null>(null)
  const panelFrameRef = ref<HTMLElement | null>(null)

  const priorityConfig: Record<TaskPriority, { color: string; label: string; glow: string }> = {
    low: { color: '#4b5563', label: 'LOW', glow: 'rgba(75,85,99,0.28)' },
    medium: { color: '#00f5d4', label: 'MED', glow: 'rgba(0,245,212,0.28)' },
    high: { color: '#f9a825', label: 'HIGH', glow: 'rgba(249,168,37,0.28)' },
    urgent: { color: '#ff4757', label: 'CRIT', glow: 'rgba(255,71,87,0.32)' },
  }

  function formatDate(date: Date) {
    const year = date.getFullYear()
    const month = String(date.getMonth() + 1).padStart(2, '0')
    const day = String(date.getDate()).padStart(2, '0')
    return `${year}-${month}-${day}`
  }

  function getMonthKey(date: Date) {
    return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}`
  }

  function formatTimelineDate(dateKey: string) {
    return dateKey.replace(/-/g, '.')
  }

  function getDayRisk(summary: ScheduleCenterDaySummary | null | undefined) {
    if (!summary) return 'LOW'

    const pressure = summary.todo_total + summary.task_due_total * 1.5 + summary.high_priority_total * 2 + summary.reminder_total
    if (pressure >= 9) return 'HIGH'
    if (pressure >= 4) return 'MED'
    return 'LOW'
  }

  function getDayState(summary: ScheduleCenterDaySummary | null | undefined) {
    if (!summary) return 'OPEN'
    if (summary.high_priority_total >= 2) return 'LOCKED'
    if (summary.task_due_total >= 4) return 'DENSE'
    if (summary.reminder_total >= 2) return 'TRACKED'
    if (summary.todo_total + summary.task_due_total + summary.goal_total > 0) return 'QUEUED'
    return 'CLEAR'
  }

  function getDayBars(summary: ScheduleCenterDaySummary | null | undefined) {
    if (!summary) return []

    return [
      { key: 'QUEUE', count: summary.todo_total, value: `${Math.min(100, summary.todo_total * 14)}%` },
      { key: 'TASK', count: summary.task_due_total, value: `${Math.min(100, summary.task_due_total * 16)}%` },
      { key: 'FOCUS', count: summary.high_priority_total, value: `${Math.min(100, summary.high_priority_total * 28)}%` },
    ].filter((item) => item.count > 0)
  }

  function getVisibleMetrics(summary: ScheduleCenterDaySummary | null | undefined) {
    if (!summary) return []

    return [
      summary.todo_total > 0 ? `待办 ${summary.todo_total}` : null,
      summary.task_due_total > 0 ? `任务 ${summary.task_due_total}` : null,
      summary.reminder_total > 0 ? `提醒 ${summary.reminder_total}` : null,
      summary.goal_total > 0 ? `目标 ${summary.goal_total}` : null,
    ].filter((item): item is string => Boolean(item))
  }

  const summaryMap = computed(() => new Map(monthSummary.value.map((item) => [item.date, item])))

  const monthOverview = computed(() =>
    monthSummary.value.reduce(
      (acc, item) => {
        acc.todo_total += item.todo_total
        acc.task_due_total += item.task_due_total
        acc.reminder_total += item.reminder_total
        acc.goal_total += item.goal_total
        acc.high_priority_total += item.high_priority_total
        return acc
      },
      { todo_total: 0, task_due_total: 0, reminder_total: 0, goal_total: 0, high_priority_total: 0 },
    ),
  )

  const calendarDays = computed(() => {
    const year = currentMonth.value.getFullYear()
    const month = currentMonth.value.getMonth()
    const daysInMonth = new Date(year, month + 1, 0).getDate()
    const firstDayOffset = (new Date(year, month, 1).getDay() + 6) % 7

    return Array.from({ length: 42 }, (_, index) => {
      const dayNumber = index - firstDayOffset + 1
      if (dayNumber < 1 || dayNumber > daysInMonth) {
        return {
          date: null,
          dateKey: `empty-${index}`,
          dayNumber: null,
          isCurrentMonth: false,
          isToday: false,
          isSelected: false,
          summary: null,
          isPlaceholder: true,
        }
      }

      const date = new Date(year, month, dayNumber)
      const dateKey = formatDate(date)
      const summary = summaryMap.value.get(dateKey) ?? null

      return {
        date,
        dateKey,
        dayNumber,
        isCurrentMonth: true,
        isToday: dateKey === formatDate(today),
        isSelected: dateKey === selectedDate.value,
        summary,
        risk: getDayRisk(summary),
        state: getDayState(summary),
        bars: getDayBars(summary),
        isPlaceholder: false,
      }
    })
  })

  const panelDateLabel = computed(() => formatTimelineDate(selectedDate.value))
  const panelSummary = computed(() => detail.value?.summary ?? null)
  const selectedTodos = computed(() => detail.value?.todos ?? [])
  const selectedTasks = computed(() => detail.value?.tasks ?? [])
  const selectedReminders = computed(() => detail.value?.reminders ?? [])
  const selectedGoals = computed(() => detail.value?.goals ?? [])
  const panelLockLabel = computed(() => (panelSummary.value?.high_priority_total ? 'Priority Lock' : 'Standard Flow'))

  const panelRings = computed(() => {
    const summary = panelSummary.value
    if (!summary) {
      return [
        { label: '负载', value: 0, tone: 'normal' },
        { label: '冲突', value: 0, tone: 'warn' },
        { label: '专注', value: 0, tone: 'alert' },
      ]
    }

    const load = Math.min(100, summary.todo_total * 10 + summary.task_due_total * 14 + summary.reminder_total * 8 + summary.goal_total * 6)
    const conflict = Math.min(100, summary.high_priority_total * 30 + summary.reminder_total * 12 + Math.max(summary.task_due_total - 2, 0) * 8)
    const focus = Math.min(100, summary.goal_total * 20 + summary.high_priority_total * 22 + summary.todo_completed * 12)

    return [
      { label: '负载', value: load, tone: 'normal' as const },
      { label: '冲突', value: conflict, tone: 'warn' as const },
      { label: '专注', value: focus, tone: 'alert' as const },
    ]
  })

  const timelineItems = computed<TimelineItem[]>(() => {
    const todos = selectedTodos.value.map<TimelineItem>((todo, index) => ({
      id: `todo-${todo.id}`,
      type: 'todo',
      tone: todo.is_completed ? 'normal' : 'warn',
      time: `${String(8 + index).padStart(2, '0')}:00`,
      label: 'Todo / Queue',
      title: todo.title,
      meta: todo.source ? `SOURCE: ${String(todo.source).toUpperCase()}` : 'SOURCE: MANUAL',
      done: todo.is_completed,
      payload: todo,
    }))

    const tasks = selectedTasks.value.map<TimelineItem>((task, index) => ({
      id: `task-${task.id}`,
      type: 'task',
      tone: task.priority === 'urgent' || task.priority === 'high' ? 'alert' : 'normal',
      time: `${String(10 + index).padStart(2, '0')}:30`,
      label: 'Task / Active',
      title: task.title,
      meta: `PRIORITY: ${priorityConfig[task.priority].label} · STATUS: ${task.status.toUpperCase()}`,
      done: task.status === 'done',
      payload: task,
    }))

    const reminders = selectedReminders.value.map<TimelineItem>((reminder) => ({
      id: `reminder-${reminder.id}`,
      type: 'reminder',
      tone: reminder.status === 'done' ? 'normal' : 'warn',
      time: reminder.reminder_at.slice(11, 16),
      label: 'Reminder / Watch',
      title: reminder.title,
      meta: `STATE: ${reminder.status.toUpperCase()}`,
      done: reminder.status === 'done',
      payload: reminder,
    }))

    const goals = selectedGoals.value.map<TimelineItem>((goal, index) => ({
      id: `goal-${goal.id}`,
      type: 'goal',
      tone: goal.status === 'done' ? 'normal' : 'alert',
      time: `${String(18 + index).padStart(2, '0')}:00`,
      label: 'Goal / Open',
      title: goal.title,
      meta: `STATE: ${goal.status.toUpperCase()}`,
      done: goal.status === 'done',
      payload: goal,
    }))

    return [...todos, ...tasks, ...reminders, ...goals].sort((a, b) => a.time.localeCompare(b.time))
  })

  async function loadMonth() {
    const requestId = monthRequestId.value + 1
    monthRequestId.value = requestId
    loadingMonth.value = true

    try {
      const response = await scheduleCenterApi.month(getMonthKey(currentMonth.value))
      if (requestId !== monthRequestId.value) return
      monthSummary.value = response.data.days
    } catch (error) {
      if (requestId !== monthRequestId.value) return
      console.error('加载月度调度数据失败', error)
      monthSummary.value = []
    } finally {
      if (requestId === monthRequestId.value) {
        loadingMonth.value = false
      }
    }
  }

  async function loadDateDetail(dateKey = selectedDate.value) {
    const requestId = detailRequestId.value + 1
    detailRequestId.value = requestId
    loadingDetail.value = true
    detail.value = null

    try {
      const response = await scheduleCenterApi.date(dateKey)
      if (requestId !== detailRequestId.value) return
      detail.value = response.data
    } catch (error) {
      if (requestId !== detailRequestId.value) return
      console.error('加载日期详情失败', error)
      detail.value = null
    } finally {
      if (requestId === detailRequestId.value) {
        loadingDetail.value = false
      }
    }
  }

  function openDate(dateKey: string) {
    selectedDate.value = dateKey
    panelOpen.value = true
    panelMode.value = 'detail'
    loadDateDetail(dateKey)
  }

  function shiftMonth(offset: number) {
    currentMonth.value = new Date(currentMonth.value.getFullYear(), currentMonth.value.getMonth() + offset, 1)
  }

  async function addTodo() {
    if (!newTodoTitle.value.trim()) return
    try {
      await todoApi.create({ title: newTodoTitle.value.trim(), todo_date: selectedDate.value })
      newTodoTitle.value = ''
      await Promise.all([loadDateDetail(), loadMonth()])
    } catch (error) {
      console.error('新增待办失败', error)
    }
  }

  async function toggleTodo(todo: Todo) {
    try {
      await todoApi.update(todo.id, { is_completed: !todo.is_completed })
      await Promise.all([loadDateDetail(), loadMonth()])
    } catch (error) {
      console.error('切换待办状态失败', error)
    }
  }

  async function removeTodo(id: string) {
    try {
      await todoApi.delete(id)
      await Promise.all([loadDateDetail(), loadMonth()])
    } catch (error) {
      console.error('删除待办失败', error)
    }
  }

  async function addTask() {
    if (!newTaskTitle.value.trim()) return
    try {
      await taskApi.create({ title: newTaskTitle.value.trim(), priority: newTaskPriority.value, due_date: `${selectedDate.value}T09:00:00Z` })
      newTaskTitle.value = ''
      newTaskPriority.value = 'medium'
      await Promise.all([loadDateDetail(), loadMonth()])
    } catch (error) {
      console.error('新增任务失败', error)
    }
  }

  async function cycleTaskStatus(task: Task) {
    const nextStatus: TaskStatus = task.status === 'todo' ? 'in_progress' : task.status === 'in_progress' ? 'done' : 'todo'
    try {
      await taskApi.update(task.id, { status: nextStatus })
      await Promise.all([loadDateDetail(), loadMonth()])
    } catch (error) {
      console.error('切换任务状态失败', error)
    }
  }

  async function removeTask(id: string) {
    try {
      await taskApi.delete(id)
      await Promise.all([loadDateDetail(), loadMonth()])
    } catch (error) {
      console.error('删除任务失败', error)
    }
  }

  async function addReminder() {
    if (!newReminderTitle.value.trim()) return
    try {
      await reminderApi.create({
        title: newReminderTitle.value.trim(),
        reminder_at: `${selectedDate.value}T${newReminderTime.value}:00Z`,
      })
      newReminderTitle.value = ''
      newReminderTime.value = '09:00'
      await Promise.all([loadDateDetail(), loadMonth()])
    } catch (error) {
      console.error('新增提醒失败', error)
    }
  }

  async function toggleReminder(reminder: Reminder) {
    try {
      await reminderApi.update(reminder.id, { status: reminder.status === 'done' ? 'pending' : 'done' })
      await Promise.all([loadDateDetail(), loadMonth()])
    } catch (error) {
      console.error('切换提醒状态失败', error)
    }
  }

  async function removeReminder(id: string) {
    try {
      await reminderApi.delete(id)
      await Promise.all([loadDateDetail(), loadMonth()])
    } catch (error) {
      console.error('删除提醒失败', error)
    }
  }

  async function addGoal() {
    if (!newGoalTitle.value.trim()) return
    try {
      await goalApi.create({ title: newGoalTitle.value.trim(), goal_date: selectedDate.value })
      newGoalTitle.value = ''
      await Promise.all([loadDateDetail(), loadMonth()])
    } catch (error) {
      console.error('新增目标失败', error)
    }
  }

  async function toggleGoal(goal: Goal) {
    try {
      await goalApi.update(goal.id, { status: goal.status === 'done' ? 'active' : 'done' })
      await Promise.all([loadDateDetail(), loadMonth()])
    } catch (error) {
      console.error('切换目标状态失败', error)
    }
  }

  async function removeGoal(id: string) {
    try {
      await goalApi.delete(id)
      await Promise.all([loadDateDetail(), loadMonth()])
    } catch (error) {
      console.error('删除目标失败', error)
    }
  }

  async function toggleTimelineItem(item: TimelineItem) {
    if (item.type === 'todo') return toggleTodo(item.payload)
    if (item.type === 'task') return cycleTaskStatus(item.payload)
    if (item.type === 'reminder') return toggleReminder(item.payload)
    return toggleGoal(item.payload)
  }

  async function removeTimelineItem(item: TimelineItem) {
    if (item.type === 'todo') return removeTodo(item.payload.id)
    if (item.type === 'task') return removeTask(item.payload.id)
    if (item.type === 'reminder') return removeReminder(item.payload.id)
    return removeGoal(item.payload.id)
  }

  watch(currentMonth, loadMonth)

  onMounted(async () => {
    await loadMonth()
    await loadDateDetail()
    panelOpen.value = true
    panelMode.value = 'detail'
  })

  function animatePanelContent() {
    const panel = panelFrameRef.value
    if (!panel) return

    const targets = panel.querySelectorAll<HTMLElement>('.panel-header, .panel-switcher, .ring-strip, .panel-loading, .timeline, .create-stack')
    targets.forEach((element, index) => {
      animate(
        element,
        {
          opacity: [0, 1],
          transform: ['translateY(14px)', 'translateY(0px)'] as const,
        } as never,
        {
          duration: 0.24,
          delay: 0.03 + index * 0.04,
          easing: [0.22, 1, 0.36, 1],
        } as never,
      )
    })
  }

  function animatePanelEnter(el: Element, done: () => void) {
    panelAnimation.value?.cancel()
    const animation = animate(
      el,
      {
        opacity: [0, 1],
        transform: ['translateX(36px) scale(0.985)', 'translateX(0px) scale(1)'] as const,
      } as never,
      {
        duration: 0.3,
        easing: [0.22, 1, 0.36, 1],
      } as never,
    )
    panelAnimation.value = animation
    animation.finished.catch(() => undefined).finally(() => {
      if (panelAnimation.value === animation) {
        panelAnimation.value = null
        requestAnimationFrame(() => animatePanelContent())
      }
      done()
    })
  }

  function animatePanelLeave(el: Element, done: () => void) {
    panelAnimation.value?.cancel()
    const animation = animate(
      el,
      {
        opacity: [1, 0],
        transform: ['translateX(0px) scale(1)', 'translateX(28px) scale(0.99)'] as const,
      } as never,
      {
        duration: 0.2,
        easing: 'ease-in',
      } as never,
    )
    panelAnimation.value = animation
    animation.finished.catch(() => undefined).finally(() => {
      if (panelAnimation.value === animation) {
        panelAnimation.value = null
      }
      done()
    })
  }

  return {
    weekdayLabels,
    currentMonth,
    panelOpen,
    loadingMonth,
    loadingDetail,
    newTodoTitle,
    newTaskTitle,
    newTaskPriority,
    newReminderTitle,
    newReminderTime,
    newGoalTitle,
    panelMode,
    panelFrameRef,
    priorityConfig,
    calendarDays,
    panelDateLabel,
    panelSummary,
    panelLockLabel,
    panelRings,
    timelineItems,
    monthOverview,
    getMonthKey,
    getVisibleMetrics,
    openDate,
    shiftMonth,
    addTodo,
    addTask,
    addReminder,
    addGoal,
    toggleTimelineItem,
    removeTimelineItem,
    animatePanelEnter,
    animatePanelLeave,
  }
}
