import { defineStore } from 'pinia'
import { ref } from 'vue'
import type { Project, Folder, Document, TreeNode, GraphData } from '@/types'
import { useApi, getToken } from '@/composables/useApi'

export const useProjectsStore = defineStore('projects', () => {
  const projects = ref<Project[]>([])
  const currentProject = ref<Project | null>(null)
  const folders = ref<Folder[]>([])
  const documents = ref<Document[]>([])
  const treeNodes = ref<TreeNode[]>([])
  const loading = ref(false)
  const error = ref<string | null>(null)

  const api = useApi()

  async function fetchProjects() {
    loading.value = true
    error.value = null
    try {
      const response = await api.get<{ projects: Project[] }>('/projects')
      projects.value = response.projects
    } catch (e) {
      error.value = e instanceof Error ? e.message : 'Failed to fetch projects'
      throw e
    } finally {
      loading.value = false
    }
  }

  async function fetchProject(id: string) {
    loading.value = true
    error.value = null
    try {
      currentProject.value = await api.get<Project>(`/projects/${id}`)
      await fetchProjectTree(id)
    } catch (e) {
      error.value = e instanceof Error ? e.message : 'Failed to fetch project'
      throw e
    } finally {
      loading.value = false
    }
  }

  async function fetchProjectTree(projectId: string) {
    try {
      const [foldersRes, docsRes] = await Promise.all([
        api.get<{ folders: Folder[] }>(`/projects/${projectId}/folders`),
        api.get<{ documents: Document[] }>(`/projects/${projectId}/documents`)
      ])

      folders.value = foldersRes.folders
      documents.value = docsRes.documents
      buildTree()
    } catch (e) {
      error.value = e instanceof Error ? e.message : 'Failed to fetch project tree'
      throw e
    }
  }

  function buildTree() {
    const folderMap = new Map<string, TreeNode>()
    const rootNodes: TreeNode[] = []

    // Create folder nodes
    for (const folder of folders.value) {
      const node: TreeNode = {
        id: folder.id,
        name: folder.name,
        type: 'folder',
        children: [],
        parent_id: folder.parent_id
      }
      folderMap.set(folder.id, node)
    }

    // Create document nodes for root-level documents
    for (const doc of documents.value) {
      if (!doc.folder_id) {
        const node: TreeNode = {
          id: doc.id,
          name: doc.title,
          type: 'document',
          parent_id: null
        }
        folderMap.set(doc.id, node)
      }
    }

    // Add documents to their parent folders
    for (const doc of documents.value) {
      if (doc.folder_id) {
        const folderNode = folderMap.get(doc.folder_id)
        if (folderNode && folderNode.children) {
          folderNode.children.push({
            id: doc.id,
            name: doc.title,
            type: 'document',
            parent_id: doc.folder_id
          })
        }
      }
    }

    // Build hierarchy
    for (const node of folderMap.values()) {
      if (node.parent_id === null) {
        rootNodes.push(node)
      } else {
        const parent = folderMap.get(node.parent_id)
        if (parent && parent.children) {
          parent.children.push(node)
        }
      }
    }

    treeNodes.value = rootNodes
  }

  async function createProject(name: string, description: string) {
    const project = await api.post<Project>('/projects', { name, description })
    projects.value.push(project)
    return project
  }

  async function updateProject(id: string, name: string, description: string) {
    const project = await api.put<Project>(`/projects/${id}`, { name, description })
    const index = projects.value.findIndex(p => p.id === id)
    if (index !== -1) {
      projects.value[index] = project
    }
    if (currentProject.value?.id === id) {
      currentProject.value = project
    }
    return project
  }

  async function deleteProject(id: string) {
    await api.delete(`/projects/${id}`)
    projects.value = projects.value.filter(p => p.id !== id)
    if (currentProject.value?.id === id) {
      currentProject.value = null
    }
  }

  async function createFolder(projectId: string, name: string, parentId: string | null = null) {
    const folder = await api.post<Folder>(`/projects/${projectId}/folders`, { name, parent_id: parentId })
    folders.value.push(folder)
    await fetchProjectTree(projectId)
    return folder
  }

  async function deleteFolder(id: string) {
    await api.delete(`/folders/${id}`)
    if (currentProject.value) {
      await fetchProjectTree(currentProject.value.id)
    }
  }

  // Phase 3: Graph
  async function fetchProjectGraph(projectId: string, depth = 2): Promise<GraphData> {
    return await api.get<GraphData>(`/projects/${projectId}/graph?depth=${depth}`)
  }

  // Phase 3: Project Export
  async function exportProject(projectId: string, format: 'zip' | 'json', includeMetadata = true): Promise<Blob> {
    const BASE_URL = import.meta.env.VITE_API_BASE_URL || 'http://localhost:8000/api/v1'
    const response = await fetch(`${BASE_URL}/projects/${projectId}/export?format=${format}&include_metadata=${includeMetadata}`, {
      headers: {
        'Authorization': `Bearer ${getToken()}`
      },
      credentials: 'include'
    })
    if (!response.ok) throw new Error('Export failed')
    return await response.blob()
  }

  return {
    projects,
    currentProject,
    folders,
    documents,
    treeNodes,
    loading,
    error,
    fetchProjects,
    fetchProject,
    fetchProjectTree,
    createProject,
    updateProject,
    deleteProject,
    createFolder,
    deleteFolder,
    // Phase 3
    fetchProjectGraph,
    exportProject
  }
})
