import type {
  CourseList,
  CourseListParams,
  CourseRow,
  FitnessGroup,
  TimeSlot,
  YesNo,
} from '@/api/types'
import { defineStore } from 'pinia'
import { computed, ref } from 'vue'
import {
  fetchCourseList,
  fetchGroup,
  fetchMorning,
  fetchNight,
  fetchNoon,
} from '@/api/course'
import { useAppStore } from '@/stores/app'

/** 後端尚未完成，預設走前端模擬資料；設定 VITE_USE_MOCK=false 即改打真實 API */
const USE_MOCK = import.meta.env.VITE_USE_MOCK !== 'false'

/** 模擬網路延遲，讓載入狀態在開發時可被觀察到 */
const MOCK_DELAY = 300

export interface GroupMeta {
  label: string
  color: string
  /** 以活動強度遞增的圖示表達組別高低，讓組別不只靠顏色辨識 */
  icon: string
  description: string
}

/** 組別的顯示資訊，文案取自 doc/課程說明.md */
export const GROUP_META: Record<FitnessGroup, GroupMeta> = {
  low: {
    label: '低體適能',
    color: 'warning',
    icon: 'mdi-walk',
    description: '肌力、平衡與心肺功能較弱，以降低跌倒風險、重建日常生活功能為優先。',
  },
  medium: {
    label: '中體適能',
    color: 'info',
    icon: 'mdi-run',
    description: '尚未失能但已出現部分衰退，重點在累積功能儲備、增加肌肉量與心肺能力。',
  },
  high: {
    label: '高體適能',
    color: 'success',
    icon: 'mdi-run-fast',
    description: '功能儲備高、跌倒風險低，目標是延緩衰退速度並長期維持既有功能。',
  },
}

/**
 * 三組一週課表，內容逐格轉錄自 doc/課程表.png。
 * 後端完成後這份資料會由第 5 支 API 提供。
 */
function createCourseTable (): Record<FitnessGroup, CourseRow[]> {
  return {
    low: [
      { day: 1, morning: '慢走 15 分鐘', noon: '正常飲食，多吃蔬菜與蛋白質', night: '坐站訓練 10 次 ×2 組＋伸展 10 分鐘' },
      { day: 2, morning: '公園散步 20 分鐘', noon: '1 顆蛋＋豆漿', night: '單腳站立和平衡訓練 15 分鐘' },
      { day: 3, morning: '慢走 15 分鐘', noon: '魚肉與青菜', night: '扶牆踮腳 15 次 ×2 組' },
      { day: 4, morning: '休閒散步 20 分鐘', noon: '補充水果', night: '伸展運動 10 分鐘' },
      { day: 5, morning: '慢走 20 分鐘', noon: '雞肉與蔬菜', night: '坐站訓練＋平衡訓練' },
      { day: 6, morning: '腳踏車或散步 30 分鐘', noon: '均衡飲食', night: '全身伸展' },
      { day: 7, morning: '輕鬆散步', noon: '與家人共餐', night: '早睡休息' },
    ],
    medium: [
      { day: 1, morning: '快走 30 分鐘', noon: '高蛋白午餐', night: '深蹲 15 次 ×3 組' },
      { day: 2, morning: '騎腳踏車 40 分鐘', noon: '水果與豆類', night: '伸展 15 分鐘' },
      { day: 3, morning: '快走 30 分鐘', noon: '魚肉與蔬菜', night: '彈力帶訓練' },
      { day: 4, morning: '游泳或太極 40 分鐘', noon: '均衡飲食', night: '核心訓練 15 分鐘' },
      { day: 5, morning: '快走 30 分鐘', noon: '高蛋白午餐', night: '深蹲＋彈力帶' },
      { day: 6, morning: '郊山健行 60 分鐘', noon: '補充水分', night: '輕鬆散步' },
      { day: 7, morning: '休息', noon: '家人聚餐', night: '伸展 10 分鐘' },
    ],
    high: [
      { day: 1, morning: '重量訓練 60 分鐘', noon: '蛋白質與蔬菜', night: '散步 20 分鐘' },
      { day: 2, morning: '快走或慢跑 45 分鐘', noon: '水果與堅果', night: '核心訓練 20 分鐘' },
      { day: 3, morning: '平衡與敏捷訓練 40 分鐘', noon: '均衡飲食', night: '伸展 15 分鐘' },
      { day: 4, morning: '重量訓練 60 分鐘', noon: '高蛋白午餐', night: '散步 20 分鐘' },
      { day: 5, morning: '間歇跑 30 分鐘', noon: '補充水分', night: '輕量伸展' },
      { day: 6, morning: '登山、羽球或游泳 90 分鐘', noon: '魚類與蔬菜', night: '放鬆休息' },
      { day: 7, morning: '輕鬆散步 30 分鐘', noon: '家人聚餐', night: '早睡恢復' },
    ],
  }
}

function delay (ms: number) {
  return new Promise(resolve => setTimeout(resolve, ms))
}

/** 模擬後端依 Y/N 篩選時段欄位的行為 */
function mockCourseList (params: CourseListParams): CourseList {
  return createCourseTable()[params.group].map(row => {
    const filtered: CourseRow = { day: row.day }

    if (params.morning === 'Y') {
      filtered.morning = row.morning
    }
    if (params.noon === 'Y') {
      filtered.noon = row.noon
    }
    if (params.night === 'Y') {
      filtered.night = row.night
    }

    return filtered
  })
}

export const useCourseStore = defineStore('course', () => {
  const group = ref<FitnessGroup>('medium')
  const morning = ref<YesNo>('Y')
  const noon = ref<YesNo>('Y')
  const night = ref<YesNo>('Y')
  const courseList = ref<CourseList>([])
  const loading = ref(false)
  const error = ref('')

  const groupMeta = computed(() => GROUP_META[group.value])

  /** 目前被選取的時段，供畫面判斷要顯示哪些欄位 */
  const selectedSlots = computed<TimeSlot[]>(() => {
    const slots: TimeSlot[] = []

    if (morning.value === 'Y') {
      slots.push('morning')
    }
    if (noon.value === 'Y') {
      slots.push('noon')
    }
    if (night.value === 'Y') {
      slots.push('night')
    }

    return slots
  })

  const hasCourse = computed(() => selectedSlots.value.length > 0 && courseList.value.length > 0)

  /** 前 4 支 API：平行取得組別與三個時段設定 */
  async function loadPreferences () {
    if (USE_MOCK) {
      await delay(MOCK_DELAY)
      group.value = 'medium'
      morning.value = 'Y'
      noon.value = 'Y'
      night.value = 'Y'
      return
    }

    // 真實後端：course/group 需要 userID，course/morning、noon、night 需要 group，
    // 兩者有相依順序，因此無法四支平行呼叫（與 doc/課程建議API規格.md 的示意圖不同，
    // 以 doc/課程建議_API_前端使用說明_20260806.md 的建議測試流程為準）
    const { userID } = useAppStore()
    const groupValue = await fetchGroup(userID)

    const [morningValue, noonValue, nightValue] = await Promise.all([
      fetchMorning(groupValue),
      fetchNoon(groupValue),
      fetchNight(groupValue),
    ])

    group.value = groupValue
    morning.value = morningValue
    noon.value = noonValue
    night.value = nightValue
  }

  /** 第 5 支 API：以前 4 個值為參數取得課表 */
  async function loadCourseList () {
    const params: CourseListParams = {
      group: group.value,
      morning: morning.value,
      noon: noon.value,
      night: night.value,
    }

    if (USE_MOCK) {
      await delay(MOCK_DELAY)
      courseList.value = mockCourseList(params)
      return
    }

    courseList.value = await fetchCourseList(params)
  }

  /** 頁面進入時呼叫：先取設定再取課表 */
  async function loadAll () {
    loading.value = true
    error.value = ''

    try {
      await loadPreferences()
      await loadCourseList()
    } catch (error_) {
      error.value = error_ instanceof Error ? error_.message : '課程資料載入失敗，請稍後再試。'
      courseList.value = []
    } finally {
      loading.value = false
    }
  }

  /** 使用者切換時段後重新取課表 */
  async function setSlot (slot: TimeSlot, value: YesNo) {
    const target = { morning, noon, night }[slot]

    if (target.value === value) {
      return
    }

    target.value = value
    loading.value = true
    error.value = ''

    try {
      await loadCourseList()
    } catch (error_) {
      error.value = error_ instanceof Error ? error_.message : '課程資料載入失敗，請稍後再試。'
      courseList.value = []
    } finally {
      loading.value = false
    }
  }

  return {
    group,
    morning,
    noon,
    night,
    courseList,
    loading,
    error,
    groupMeta,
    selectedSlots,
    hasCourse,
    loadAll,
    loadCourseList,
    loadPreferences,
    setSlot,
  }
})
