import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import { projectsApi, usersApi, cardsApi, projectInviteApi } from '../api'
import { getCachedUser } from '../router'

// ==================== ЛОКАЛЬНЫЙ ПОРЯДОК ПРОЕКТОВ ====================
const PROJECTS_ORDER_KEY = 'projectsOrder'

// Получить сохранённый порядок из localStorage
const getLocalProjectsOrder = () => {
  try {
    const saved = localStorage.getItem(PROJECTS_ORDER_KEY)
    return saved ? JSON.parse(saved) : []
  } catch {
    return []
  }
}

// Сохранить порядок в localStorage
const saveLocalProjectsOrder = (ids) => {
  localStorage.setItem(PROJECTS_ORDER_KEY, JSON.stringify(ids))
}

// Применить локальный порядок к массиву проектов
const applyLocalOrder = (projectsArray) => {
  const savedOrder = getLocalProjectsOrder()
  if (!savedOrder.length) return projectsArray
  
  // Создаём Map для быстрого доступа
  const projectsMap = new Map(projectsArray.map(p => [p.id, p]))
  const result = []
  
  // Сначала добавляем проекты в сохранённом порядке
  for (const id of savedOrder) {
    if (projectsMap.has(id)) {
      result.push(projectsMap.get(id))
      projectsMap.delete(id)
    }
  }
  
  // Затем добавляем новые проекты (которых нет в сохранённом порядке)
  for (const project of projectsMap.values()) {
    result.push(project)
  }
  
  return result
}

export const useProjectsStore = defineStore('projects', () => {
  // ==================== СОСТОЯНИЕ ====================
  const projects = ref([])
  const departments = ref([])
  const labels = ref([])
  const columns = ref([])
  const users = ref([])
  const cards = ref([])              // Активные карточки текущего проекта
  const archivedCards = ref([])      // Архивные карточки текущего проекта
  const cardsLoading = ref(false)    // Загрузка карточек
  const loading = ref(false)
  const initialized = ref(false)
  const currentUser = ref(null)  // Текущий авторизованный пользователь
  const pendingInvitesCount = ref(0)  // Количество pending-приглашений

  // Текущий проект (из localStorage)
  const savedProjectId = localStorage.getItem('currentProjectId')
  const savedProjectName = localStorage.getItem('currentProjectName')
  const currentProjectId = ref(savedProjectId ? parseInt(savedProjectId) : null)

  // ==================== ГЕТТЕРЫ ====================
  // Текущий проект (объект)
  const currentProject = computed(() => 
    projects.value.find(p => p.id === currentProjectId.value) || 
    (savedProjectName && currentProjectId.value ? { id: currentProjectId.value, name: savedProjectName } : null)
  )

  // ID колонки "Готово" текущего проекта
  const doneColumnId = computed(() => {
    const project = projects.value.find(p => p.id === currentProjectId.value)
    return project ? Number(project.id_ready) : null
  })

  // ID текущего пользователя (приводим к числу для корректного сравнения)
  const currentUserId = computed(() => currentUser.value?.id ? Number(currentUser.value.id) : null)
  
  // Имя текущего пользователя
  const currentUserName = computed(() => currentUser.value?.name || '')
  
  // Аватар текущего пользователя
  const currentUserAvatar = computed(() => currentUser.value?.avatar_url || '')

  // Является ли текущий пользователь админом проекта
  const isProjectAdmin = computed(() => {
    const project = projects.value.find(p => p.id === currentProjectId.value)
    return project?.is_admin === true
  })

  // Права текущего пользователя в проекте (загружаются с users)
  const currentUserPermissions = computed(() => {
    if (!currentUserId.value) return {}
    const member = users.value.find(u => u.id_user === currentUserId.value)
    return member?.permissions || {}
  })

  // Проверка конкретного права (админ имеет все права)
  const can = (permission) => {
    if (isProjectAdmin.value) return true
    return currentUserPermissions.value[permission] === true
  }

  // Проверка права на редактирование задачи
  const canEditTask = (task) => {
    if (!currentUserId.value) return false
    if (isProjectAdmin.value) return true
    if (can('edit_task')) return true
    
    const creatorId = task?.create_id_account ? Number(task.create_id_account) : null
    // accountId (mapped) или id_account (raw)
    const assigneeId = task?.accountId ? Number(task.accountId) : (task?.id_account ? Number(task.id_account) : null)
    
    // Создатель + право создания → может редактировать
    if (creatorId === currentUserId.value && can('create_task')) return true
    
    // Назначена на себя + право edit_own_task_only
    if (assigneeId === currentUserId.value && can('edit_own_task_only')) return true
    
    return false
  }

  // Проверка права на перемещение задачи
  const canMoveTask = (task) => {
    if (!currentUserId.value) return false
    if (isProjectAdmin.value) return true
    if (can('move_task')) return true
    
    const creatorId = task?.create_id_account ? Number(task.create_id_account) : null
    // accountId (mapped) или id_account (raw)
    const assigneeId = task?.accountId ? Number(task.accountId) : (task?.id_account ? Number(task.id_account) : null)
    
    // Создатель + право создания → может перемещать
    if (creatorId === currentUserId.value && can('create_task')) return true
    
    // Назначена на себя + право move_own_task_only
    if (assigneeId === currentUserId.value && can('move_own_task_only')) return true
    
    return false
  }

  // Проверка права на создание комментария в задаче
  const canCreateComment = (task) => {
    if (!currentUserId.value) return false
    if (isProjectAdmin.value) return true
    if (can('create_comment')) return true
    
    const creatorId = task?.create_id_account ? Number(task.create_id_account) : null
    // accountId (mapped) или id_account (raw)
    const assigneeId = task?.accountId ? Number(task.accountId) : (task?.id_account ? Number(task.id_account) : null)
    
    // Создатель + право создания → может комментировать
    if (creatorId === currentUserId.value && can('create_task')) return true
    
    // Назначена на себя + право create_comment_own_task_only
    if (assigneeId === currentUserId.value && can('create_comment_own_task_only')) return true
    
    return false
  }

  // ==================== ДЕЙСТВИЯ ====================
  // Инициализация (загрузка проектов + данных активного)
  const init = async () => {
    // Если уже инициализировано И есть данные — пропускаем
    if (initialized.value && projects.value.length > 0) return
    loading.value = true
    
    try {
      // Загружаем проекты и данные активного одним запросом
      const result = await projectsApi.getAll(currentProjectId.value || undefined)
      
      if (result.success) {
        if (result.data.projects) {
          // Применяем локальный порядок сортировки
          projects.value = applyLocalOrder(result.data.projects)
          
          // Применяем данные активного проекта
          if (result.data.active) {
            columns.value = result.data.active.columns
            departments.value = result.data.active.departments
            labels.value = result.data.active.labels
          }
        } else {
          // Применяем локальный порядок сортировки
          projects.value = applyLocalOrder(result.data)
        }
        
        // Если нет проектов — очищаем currentProjectId
        if (projects.value.length === 0) {
          currentProjectId.value = null
          localStorage.removeItem('currentProjectId')
          localStorage.removeItem('currentProjectName')
        }
        // Если нет выбранного проекта — выбираем первый
        else if (!currentProjectId.value || !projects.value.find(p => p.id === currentProjectId.value)) {
          if (projects.value.length > 0) {
            await selectProject(projects.value[0].id, true)  // Загружаем данные проекта
          }
        } else if (!columns.value.length) {
          // Есть проект но нет данных — загружаем
          await fetchProjectData()
        } else {
          // Обновляем название в localStorage
          const project = projects.value.find(p => p.id === currentProjectId.value)
          if (project) localStorage.setItem('currentProjectName', project.name)
        }
      }
      
      // Получаем текущего пользователя из кэша роутера
      if (!currentUser.value) {
        const cachedUser = getCachedUser()
        if (cachedUser) {
          currentUser.value = cachedUser
        }
      }
      
      // Загружаем участников проекта (users теперь привязаны к проекту)
      if (currentProjectId.value) {
        await fetchUsers()
        // Загружаем количество pending-приглашений (только если есть проекты)
        // Если проектов нет — NoProjectsPage сама загрузит полные данные с count
        await fetchPendingInvitesCount()
      }
      
      initialized.value = true
    } catch (error) {
      console.error('Ошибка инициализации:', error)
    } finally {
      loading.value = false
    }
  }

  // Принудительная перезагрузка проектов (для обновления после принятия приглашения/выхода из проекта)
  const refreshProjects = async () => {
    loading.value = true
    
    try {
      const result = await projectsApi.getAll()
      
      if (result.success) {
        if (result.data.projects) {
          // Применяем локальный порядок сортировки
          projects.value = applyLocalOrder(result.data.projects)
        } else {
          // Применяем локальный порядок сортировки
          projects.value = applyLocalOrder(result.data)
        }
        
        // Если нет проектов — очищаем currentProjectId
        if (projects.value.length === 0) {
          currentProjectId.value = null
          columns.value = []
          departments.value = []
          labels.value = []
          users.value = []
          cards.value = []
          archivedCards.value = []
          localStorage.removeItem('currentProjectId')
          localStorage.removeItem('currentProjectName')
        }
        // Проверяем, есть ли текущий проект в списке
        else if (currentProjectId.value && !projects.value.find(p => p.id === currentProjectId.value)) {
          // Текущий проект больше недоступен — переключаемся на первый
          await selectProject(projects.value[0].id, true)
        }
      }
      
      // Устанавливаем текущего пользователя из кэша (если ещё не установлен)
      if (!currentUser.value) {
        const cachedUser = getCachedUser()
        if (cachedUser) {
          currentUser.value = cachedUser
        }
      }
      
      // Обновляем количество pending-приглашений
      await fetchPendingInvitesCount()
      
      initialized.value = true
    } catch (error) {
      console.error('Ошибка перезагрузки проектов:', error)
    } finally {
      loading.value = false
    }
  }

  // Выбор проекта
  const selectProject = async (projectId, fetchData = true) => {
    currentProjectId.value = projectId
    localStorage.setItem('currentProjectId', projectId.toString())
    
    // Сохраняем название
    const project = projects.value.find(p => p.id === projectId)
    if (project) localStorage.setItem('currentProjectName', project.name)
    
    // Загружаем данные проекта
    if (fetchData) {
      await fetchProjectData()
    }
  }

  // Загрузка данных текущего проекта
  const fetchProjectData = async () => {
    if (!currentProjectId.value) return
    
    try {
      const projectData = await projectsApi.getData(currentProjectId.value)
      
      if (projectData.success) {
        columns.value = projectData.data.columns
        departments.value = projectData.data.departments
        labels.value = projectData.data.labels
        
        // Обновляем is_admin в списке проектов
        const project = projects.value.find(p => p.id === currentProjectId.value)
        if (project && projectData.data.project?.is_admin === true) {
          project.is_admin = true
        }
      }
      
      // Загружаем участников проекта
      await fetchUsers()
    } catch (error) {
      console.error('Ошибка загрузки данных проекта:', error)
    }
  }

  // Загрузка участников проекта
  const fetchUsers = async () => {
    if (!currentProjectId.value) return
    
    try {
      const usersData = await usersApi.getAll(currentProjectId.value)
      if (usersData.success) {
        users.value = usersData.data
      }
    } catch (error) {
      console.error('Ошибка загрузки участников:', error)
    }
  }

  // Загрузка количества pending-приглашений
  const fetchPendingInvitesCount = async () => {
    try {
      const result = await projectInviteApi.getCount()
      if (result.success) {
        pendingInvitesCount.value = result.count
      }
    } catch (error) {
      console.error('Ошибка загрузки приглашений:', error)
    }
  }

  // ==================== КАРТОЧКИ ====================
  // Загрузка активных карточек (silent = тихое обновление без loading)
  const fetchCards = async (silent = false) => {
    if (!currentProjectId.value) {
      cardsLoading.value = false
      return
    }
    
    if (!silent) cardsLoading.value = true
    try {
      const result = await cardsApi.getAll(currentProjectId.value)
      if (result.success) cards.value = result.data
    } finally {
      if (!silent) cardsLoading.value = false
    }
  }

  // Загрузка архивных карточек
  const fetchArchivedCards = async () => {
    if (!currentProjectId.value) return
    
    cardsLoading.value = true
    try {
      const result = await cardsApi.getAll(currentProjectId.value, 1) // archive = 1
      if (result.success) {
        archivedCards.value = result.data.map(card => ({
          id: card.id,
          title: card.title,
          description: card.descript,
          details: card.descript_full,
          departmentId: card.id_department,
          labelId: card.id_label,
          accountId: card.id_account,
          assignee: card.avatar_img,
          dueDate: card.date,
          dateCreate: card.date_create,
          dateClosed: card.date_closed,
          columnId: card.column_id,
          order: card.order ?? 0,
          comments_count: card.comments_count || 0,
          files: card.files || (card.file_img || []).map(f => ({
            name: f.name,
            url: f.url,
            size: f.size,
            preview: f.url
          }))
        }))
      }
    } finally {
      cardsLoading.value = false
    }
  }

  // Очистка карточек при смене проекта
  const clearCards = () => {
    cards.value = []
    archivedCards.value = []
  }

  // Сброс при выходе
  const reset = () => {
    projects.value = []
    departments.value = []
    labels.value = []
    columns.value = []
    users.value = []
    cards.value = []
    archivedCards.value = []
    currentProjectId.value = null
    currentUser.value = null
    pendingInvitesCount.value = 0
    initialized.value = false
    localStorage.removeItem('currentProjectId')
    localStorage.removeItem('currentProjectName')
    localStorage.removeItem(PROJECTS_ORDER_KEY)
  }

  // ==================== CRUD ПРОЕКТОВ ====================

  // Создание проекта
  const createProject = async (name) => {
    const result = await projectsApi.create(name)
    if (result.success) {
      // Добавляем проект в список
      const newProject = {
        id: result.id,
        name,
        id_ready: result.id_ready,
        is_admin: true // Создатель = админ
      }
      projects.value.push(newProject)
      
      // Добавляем в локальный порядок
      const currentOrder = getLocalProjectsOrder()
      currentOrder.push(result.id)
      saveLocalProjectsOrder(currentOrder)
      
      // Переключаемся на новый проект
      await selectProject(result.id)
    }
    return result
  }

  // Обновление проекта
  const updateProject = async (id, name) => {
    const result = await projectsApi.update(id, name)
    if (result.success) {
      const project = projects.value.find(p => p.id === id)
      if (project) {
        project.name = name
        // Обновляем localStorage если это текущий проект
        if (id === currentProjectId.value) {
          localStorage.setItem('currentProjectName', name)
        }
      }
    }
    return result
  }

  // Удаление проекта
  const deleteProject = async (id) => {
    const result = await projectsApi.delete(id)
    if (result.success) {
      const index = projects.value.findIndex(p => p.id === id)
      if (index !== -1) {
        projects.value.splice(index, 1)
      }
      
      // Удаляем из локального порядка
      const currentOrder = getLocalProjectsOrder()
      const filteredOrder = currentOrder.filter(pid => pid !== id)
      saveLocalProjectsOrder(filteredOrder)
      
      // Если удалили текущий проект — переключаемся на первый
      if (id === currentProjectId.value) {
        if (projects.value.length > 0) {
          await selectProject(projects.value[0].id)
        } else {
          currentProjectId.value = null
          columns.value = []
          departments.value = []
          cards.value = []
          localStorage.removeItem('currentProjectId')
          localStorage.removeItem('currentProjectName')
        }
      }
    }
    return result
  }

  // Обновление порядка проектов (локально, без отправки на сервер)
  const reorderProjects = (ids) => {
    // Применяем новый порядок
    const reordered = ids.map((id, index) => {
      const project = projects.value.find(p => p.id === id)
      return { ...project }
    }).filter(Boolean)
    projects.value = reordered
    
    // Сохраняем порядок локально
    saveLocalProjectsOrder(ids)
  }

  // ==================== CRUD КОЛОНОК ====================

  // Добавление колонки
  const addColumn = async (name, color = '#6366f1') => {
    if (!currentProjectId.value) return { success: false }
    
    const result = await projectsApi.addColumn(currentProjectId.value, name, color)
    if (result.success) {
      columns.value.push(result.column)
    }
    return result
  }

  // Обновление колонки
  const updateColumn = async (id, name, color) => {
    const result = await projectsApi.updateColumn(id, name, color)
    if (result.success) {
      const column = columns.value.find(c => c.id === id)
      if (column) {
        if (name !== null && name !== undefined) column.name_columns = name
        if (color !== null && color !== undefined) column.color = color
      }
    }
    return result
  }

  // Получение количества задач в колонке
  const getColumnTasksCount = async (id) => {
    const result = await projectsApi.getColumnTasksCount(id)
    return result.success ? result.count : 0
  }

  // Удаление колонки
  const deleteColumn = async (id) => {
    const result = await projectsApi.deleteColumn(id)
    if (result.success) {
      const index = columns.value.findIndex(c => c.id === id)
      if (index !== -1) {
        columns.value.splice(index, 1)
      }
      // Удаляем карточки этой колонки из локального состояния
      cards.value = cards.value.filter(c => c.column_id !== id)
    }
    return result
  }

  // Обновление порядка колонок
  const reorderColumns = async (ids) => {
    if (!currentProjectId.value) return
    
    // Оптимистичное обновление
    const reordered = ids.map((id, index) => {
      const column = columns.value.find(c => c.id === id)
      return { ...column, id_order: index + 1 }
    })
    columns.value = reordered
    
    // Отправляем на сервер
    await projectsApi.updateColumnsOrder(currentProjectId.value, ids)
  }

  // Установка финальной колонки
  const setReadyColumn = async (columnId) => {
    if (!currentProjectId.value) return { success: false }
    
    const result = await projectsApi.setReadyColumn(currentProjectId.value, columnId)
    if (result.success) {
      // Обновляем id_ready в проекте
      const project = projects.value.find(p => p.id === currentProjectId.value)
      if (project) {
        project.id_ready = columnId
      }
    }
    return result
  }

  // ==================== CRUD ОТДЕЛОВ ====================

  // Добавление отдела
  const addDepartment = async (name, color = '#6366f1') => {
    if (!currentProjectId.value) return { success: false }
    
    const result = await projectsApi.addDepartment(currentProjectId.value, name, color)
    if (result.success) {
      departments.value.push(result.department)
    }
    return result
  }

  // Обновление отдела
  const updateDepartment = async (id, name, color) => {
    const result = await projectsApi.updateDepartment(id, name, color)
    if (result.success) {
      const department = departments.value.find(d => d.id === id)
      if (department) {
        if (name !== null && name !== undefined) department.name_departments = name
        if (color !== null && color !== undefined) department.color = color
      }
    }
    return result
  }

  // Получение количества задач в отделе
  const getDepartmentTasksCount = async (id) => {
    const result = await projectsApi.getDepartmentTasksCount(id)
    return result.success ? result.count : 0
  }

  // Удаление отдела
  const deleteDepartment = async (id) => {
    const result = await projectsApi.deleteDepartment(id)
    if (result.success) {
      const index = departments.value.findIndex(d => d.id === id)
      if (index !== -1) {
        departments.value.splice(index, 1)
      }
      // Обнуляем id_department у карточек этого отдела
      cards.value.forEach(card => {
        if (card.id_department === id) {
          card.id_department = null
        }
      })
    }
    return result
  }

  // Обновление порядка отделов
  const reorderDepartments = async (ids) => {
    if (!currentProjectId.value) return
    
    // Оптимистичное обновление
    const reordered = ids.map((id, index) => {
      const department = departments.value.find(d => d.id === id)
      return { ...department, order_id: index + 1 }
    })
    departments.value = reordered
    
    // Отправляем на сервер
    await projectsApi.updateDepartmentsOrder(currentProjectId.value, ids)
  }

  // Добавление отдела в конкретный проект (для создания нового проекта)
  const addDepartmentToProject = async (projectId, name, color = '#6366f1') => {
    const result = await projectsApi.addDepartment(projectId, name, color)
    // Не добавляем в локальный state — при переключении на проект данные загрузятся
    return result
  }

  return {
    // Состояние
    projects,
    departments,
    labels,
    columns,
    users,
    cards,
    archivedCards,
    cardsLoading,
    loading,
    initialized,
    currentProjectId,
    currentUser,
    pendingInvitesCount,
    // Геттеры
    currentProject,
    doneColumnId,
    currentUserId,
    currentUserName,
    currentUserAvatar,
    isProjectAdmin,
    currentUserPermissions,
    // Проверки прав
    can,
    canEditTask,
    canMoveTask,
    canCreateComment,
    // Действия
    init,
    refreshProjects,
    selectProject,
    fetchProjectData,
    fetchUsers,
    fetchPendingInvitesCount,
    fetchCards,
    fetchArchivedCards,
    clearCards,
    reset,
    // CRUD проектов
    createProject,
    updateProject,
    deleteProject,
    reorderProjects,
    // CRUD колонок
    addColumn,
    updateColumn,
    getColumnTasksCount,
    deleteColumn,
    reorderColumns,
    setReadyColumn,
    // CRUD отделов
    addDepartment,
    addDepartmentToProject,
    updateDepartment,
    getDepartmentTasksCount,
    deleteDepartment,
    reorderDepartments
  }
})
