import { defineStore } from 'pinia'
import { ref } from 'vue'
import { api } from '../composables/useApi'

export const usePlannerStore = defineStore('planner', () => {
  const notes = ref([])
  const todos = ref([])
  const inbox = ref([])
  const reminders = ref([])
  const goals = ref([])
  const checklists = ref([])
  const sleepRecords = ref([])
  const gymRecords = ref([])
  const periodRecords = ref([])
  const docs = ref([])
  const bugs = ref([])
  const reviews = ref([])
  const healthItems = ref([])
  const healthPlans = ref([])
  const healthChecks = ref([])
  const musicItems = ref([])
  const musicPlans = ref([])
  const musicChecks = ref([])
  const scheduleModules = ref([])
  const scheduleSlots = ref([])
  const weeklyTemplate = ref([])
  const loading = ref(false)

  async function loadAll() {
    loading.value = true
    try {
      const [
        notesData, todosData, inboxData, remindersData,
        goalsData, checklistsData, sleepData, gymData,
        periodData, docsData, bugsData, reviewsData,
        hItems, hPlans, hChecks,
        mItems, mPlans, mChecks,
        sMods, sSlots, wTemplate,
      ] = await Promise.all([
        api.get('/api/notes'),
        api.get('/api/todos'),
        api.get('/api/inbox'),
        api.get('/api/reminders'),
        api.get('/api/goals'),
        api.get('/api/checklists'),
        api.get('/api/sleep'),
        api.get('/api/gym'),
        api.get('/api/period'),
        api.get('/api/docs'),
        api.get('/api/bugs'),
        api.get('/api/reviews'),
        api.get('/api/health-items?type=health'),
        api.get('/api/health-plans?type=health'),
        api.get('/api/health-checks?type=health'),
        api.get('/api/health-items?type=music'),
        api.get('/api/health-plans?type=music'),
        api.get('/api/health-checks?type=music'),
        api.get('/api/schedule-modules'),
        api.get('/api/schedule-slots'),
        api.get('/api/weekly-template'),
      ])
      notes.value = notesData
      todos.value = todosData
      inbox.value = inboxData
      reminders.value = remindersData
      goals.value = goalsData
      checklists.value = checklistsData
      sleepRecords.value = sleepData
      gymRecords.value = gymData
      periodRecords.value = periodData
      docs.value = docsData
      bugs.value = bugsData
      reviews.value = reviewsData
      healthItems.value = hItems
      healthPlans.value = hPlans
      healthChecks.value = hChecks
      musicItems.value = mItems
      musicPlans.value = mPlans
      musicChecks.value = mChecks
      scheduleModules.value = sMods
      scheduleSlots.value = sSlots
      weeklyTemplate.value = wTemplate
    } finally {
      loading.value = false
    }
  }

  // ---- Notes ----
  async function addNote(note) {
    await api.post('/api/notes', note)
    notes.value.unshift(note)
  }
  async function deleteNote(id) {
    await api.del(`/api/notes/${id}`)
    notes.value = notes.value.filter(n => n.id !== id)
  }
  async function updateNote(note) {
    await api.post('/api/notes', note)
    const idx = notes.value.findIndex(n => n.id === note.id)
    if (idx >= 0) notes.value[idx] = { ...notes.value[idx], ...note }
  }

  // ---- Todos ----
  async function addTodo(todo) {
    await api.post('/api/todos', todo)
    todos.value.unshift(todo)
  }
  async function updateTodo(todo) {
    await api.post('/api/todos', todo)
    const idx = todos.value.findIndex(t => t.id === todo.id)
    if (idx >= 0) todos.value[idx] = { ...todos.value[idx], ...todo }
  }
  async function deleteTodo(id) {
    await api.del(`/api/todos/${id}`)
    todos.value = todos.value.filter(t => t.id !== id)
  }

  // ---- Inbox ----
  async function addInbox(item) {
    await api.post('/api/inbox', item)
    inbox.value.unshift(item)
  }
  async function deleteInbox(id) {
    await api.del(`/api/inbox/${id}`)
    inbox.value = inbox.value.filter(i => i.id !== id)
  }
  async function clearInbox() {
    await api.del('/api/inbox')
    inbox.value = []
  }

  // ---- Reminders ----
  async function addReminder(r) {
    await api.post('/api/reminders', r)
    reminders.value.push(r)
  }
  async function updateReminder(r) {
    await api.post('/api/reminders', r)
    const idx = reminders.value.findIndex(x => x.id === r.id)
    if (idx >= 0) reminders.value[idx] = { ...reminders.value[idx], ...r }
  }
  async function deleteReminder(id) {
    await api.del(`/api/reminders/${id}`)
    reminders.value = reminders.value.filter(r => r.id !== id)
  }

  // ---- Goals ----
  async function addGoal(g) {
    await api.post('/api/goals', g)
    goals.value.unshift(g)
  }
  async function updateGoal(g) {
    await api.post('/api/goals', g)
    const idx = goals.value.findIndex(x => x.id === g.id)
    if (idx >= 0) goals.value[idx] = { ...goals.value[idx], ...g }
  }
  async function deleteGoal(id) {
    await api.del(`/api/goals/${id}`)
    goals.value = goals.value.filter(g => g.id !== id)
  }

  // ---- Checklists ----
  async function addChecklist(cl) {
    await api.post('/api/checklists', cl)
    checklists.value.unshift(cl)
  }
  async function updateChecklist(cl) {
    await api.post('/api/checklists', cl)
    const idx = checklists.value.findIndex(x => x.id === cl.id)
    if (idx >= 0) checklists.value[idx] = { ...checklists.value[idx], ...cl }
  }
  async function deleteChecklist(id) {
    await api.del(`/api/checklists/${id}`)
    checklists.value = checklists.value.filter(c => c.id !== id)
  }

  // ---- Sleep ----
  async function addSleep(record) {
    await api.post('/api/sleep', record)
    const idx = sleepRecords.value.findIndex(r => r.date === record.date)
    if (idx >= 0) sleepRecords.value[idx] = record
    else sleepRecords.value.unshift(record)
  }
  async function deleteSleep(date) {
    await api.del(`/api/sleep/${date}`)
    sleepRecords.value = sleepRecords.value.filter(r => r.date !== date)
  }

  // ---- Gym ----
  async function addGym(record) {
    await api.post('/api/gym', record)
    gymRecords.value.unshift(record)
  }
  async function deleteGym(id) {
    await api.del(`/api/gym/${id}`)
    gymRecords.value = gymRecords.value.filter(r => r.id !== id)
  }

  // ---- Period ----
  async function addPeriod(record) {
    await api.post('/api/period', record)
    periodRecords.value.unshift(record)
  }
  async function updatePeriod(record) {
    await api.post('/api/period', record)
    const idx = periodRecords.value.findIndex(r => r.id === record.id)
    if (idx >= 0) periodRecords.value[idx] = { ...periodRecords.value[idx], ...record }
  }
  async function deletePeriod(id) {
    await api.del(`/api/period/${id}`)
    periodRecords.value = periodRecords.value.filter(r => r.id !== id)
  }

  // ---- Docs ----
  async function addDoc(doc) {
    await api.post('/api/docs', doc)
    docs.value.push({ ...doc, entries: [] })
  }
  async function updateDoc(doc) {
    await api.post('/api/docs', doc)
    const idx = docs.value.findIndex(d => d.id === doc.id)
    if (idx >= 0) docs.value[idx] = { ...docs.value[idx], ...doc }
  }
  async function deleteDoc(id) {
    await api.del(`/api/docs/${id}`)
    docs.value = docs.value.filter(d => d.id !== id)
  }
  async function addDocEntry(entry) {
    await api.post('/api/doc-entries', entry)
    const doc = docs.value.find(d => d.id === entry.doc_id)
    if (doc) {
      if (!doc.entries) doc.entries = []
      doc.entries.unshift(entry)
    }
  }
  async function deleteDocEntry(entryId, docId) {
    await api.del(`/api/doc-entries/${entryId}`)
    const doc = docs.value.find(d => d.id === docId)
    if (doc) doc.entries = doc.entries.filter(e => e.id !== entryId)
  }

  // ---- Bugs ----
  async function addBug(bug) {
    await api.post('/api/bugs', bug)
    bugs.value.unshift(bug)
  }
  async function updateBug(bug) {
    await api.post('/api/bugs', bug)
    const idx = bugs.value.findIndex(b => b.id === bug.id)
    if (idx >= 0) bugs.value[idx] = { ...bugs.value[idx], ...bug }
  }
  async function deleteBug(id) {
    await api.del(`/api/bugs/${id}`)
    bugs.value = bugs.value.filter(b => b.id !== id)
  }

  // ---- Reviews ----
  async function saveReview(review) {
    await api.post('/api/reviews', review)
    const idx = reviews.value.findIndex(r => r.week === review.week)
    if (idx >= 0) reviews.value[idx] = review
    else reviews.value.unshift(review)
  }

  // ---- Health check-in ----
  async function addHealthItem(item) {
    await api.post('/api/health-items', item)
    if (item.type === 'music') musicItems.value.push(item)
    else healthItems.value.push(item)
  }
  async function deleteHealthItem(id) {
    await api.del(`/api/health-items/${id}`)
    healthItems.value = healthItems.value.filter(i => i.id !== id)
    musicItems.value = musicItems.value.filter(i => i.id !== id)
  }
  async function saveHealthPlan(plan) {
    await api.post('/api/health-plans', plan)
    const list = plan.type === 'music' ? musicPlans : healthPlans
    const idx = list.value.findIndex(p => p.month === plan.month && p.type === plan.type)
    if (idx >= 0) list.value[idx] = plan
    else list.value.push(plan)
  }
  async function toggleHealthCheck(check) {
    await api.post('/api/health-checks', check)
    const list = check.type === 'music' ? musicChecks : healthChecks
    if (check.checked) {
      list.value.push(check)
    } else {
      list.value = list.value.filter(
        c => !(c.date === check.date && c.type === check.type && c.item_id === check.item_id)
      )
    }
  }

  // ---- Schedule ----
  async function addScheduleModule(m) {
    await api.post('/api/schedule-modules', m)
    scheduleModules.value.push(m)
  }
  async function updateScheduleModule(m) {
    await api.post('/api/schedule-modules', m)
    const idx = scheduleModules.value.findIndex(x => x.id === m.id)
    if (idx >= 0) scheduleModules.value[idx] = { ...scheduleModules.value[idx], ...m }
  }
  async function deleteScheduleModule(id) {
    await api.del(`/api/schedule-modules/${id}`)
    scheduleModules.value = scheduleModules.value.filter(m => m.id !== id)
    scheduleSlots.value = scheduleSlots.value.filter(s => s.module_id !== id)
  }
  async function addScheduleSlot(slot) {
    await api.post('/api/schedule-slots', slot)
    scheduleSlots.value.push(slot)
  }
  async function removeScheduleSlot(date, timeSlot, moduleId) {
    await api.del(`/api/schedule-slots?date=${date}&time_slot=${timeSlot}&module_id=${moduleId}`)
    scheduleSlots.value = scheduleSlots.value.filter(
      s => !(s.date === date && s.time_slot === timeSlot && s.module_id === moduleId)
    )
  }
  async function clearScheduleDay(date) {
    await api.del(`/api/schedule-slots?date=${date}`)
    scheduleSlots.value = scheduleSlots.value.filter(s => s.date !== date)
  }

  // ---- Weekly Template ----
  async function saveWeeklyTemplate(day, data) {
    await api.post('/api/weekly-template', { day, data: JSON.stringify(data) })
    const idx = weeklyTemplate.value.findIndex(t => t.day === day)
    if (idx >= 0) weeklyTemplate.value[idx].data = JSON.stringify(data)
    else weeklyTemplate.value.push({ day, data: JSON.stringify(data) })
  }

  return {
    // State
    notes, todos, inbox, reminders, goals, checklists,
    sleepRecords, gymRecords, periodRecords, docs, bugs, reviews,
    healthItems, healthPlans, healthChecks,
    musicItems, musicPlans, musicChecks,
    scheduleModules, scheduleSlots, weeklyTemplate,
    loading,
    // Actions
    loadAll,
    addNote, deleteNote, updateNote,
    addTodo, updateTodo, deleteTodo,
    addInbox, deleteInbox, clearInbox,
    addReminder, updateReminder, deleteReminder,
    addGoal, updateGoal, deleteGoal,
    addChecklist, updateChecklist, deleteChecklist,
    addSleep, deleteSleep,
    addGym, deleteGym,
    addPeriod, updatePeriod, deletePeriod,
    addDoc, updateDoc, deleteDoc, addDocEntry, deleteDocEntry,
    addBug, updateBug, deleteBug,
    saveReview,
    addHealthItem, deleteHealthItem, saveHealthPlan, toggleHealthCheck,
    addScheduleModule, updateScheduleModule, deleteScheduleModule,
    addScheduleSlot, removeScheduleSlot, clearScheduleDay,
    saveWeeklyTemplate,
  }
})
