import {
  createContext,
  useState,
  useEffect,
  useCallback,
  type ReactNode,
} from 'react'
import { projectService, type Project } from '@/services'
import { useAuth } from '@/hooks'

export interface ProjectContextType {
  projects: Project[]
  currentProject: Project | null
  isLoading: boolean
  error: string | null
  setCurrentProject: (project: Project | null) => void
  refreshProjects: () => Promise<void>
  createProject: (name: string, description?: string) => Promise<Project>
}

export const ProjectContext = createContext<ProjectContextType | undefined>(undefined)

const STORAGE_KEY = 'selectedProjectId'

interface ProjectProviderProps {
  children: ReactNode
}

export function ProjectProvider({ children }: ProjectProviderProps) {
  const { isAuthenticated, isLoading: authLoading } = useAuth()
  const [projects, setProjects] = useState<Project[]>([])
  const [currentProject, setCurrentProjectState] = useState<Project | null>(null)
  const [isLoading, setIsLoading] = useState(true)
  const [error, setError] = useState<string | null>(null)

  const setCurrentProject = useCallback((project: Project | null) => {
    setCurrentProjectState(project)
    if (project) {
      localStorage.setItem(STORAGE_KEY, project.id.toString())
    } else {
      localStorage.removeItem(STORAGE_KEY)
    }
  }, [])

  const refreshProjects = useCallback(async () => {
    if (!isAuthenticated) {
      setProjects([])
      setCurrentProjectState(null)
      setIsLoading(false)
      return
    }

    try {
      setIsLoading(true)
      setError(null)
      const fetchedProjects = await projectService.getMyProjects()
      setProjects(fetchedProjects)

      // Restore selected project from localStorage or select first available
      const savedProjectId = localStorage.getItem(STORAGE_KEY)
      if (savedProjectId) {
        const savedProject = fetchedProjects.find(
          (p) => p.id === parseInt(savedProjectId, 10)
        )
        if (savedProject) {
          setCurrentProjectState(savedProject)
        } else if (fetchedProjects.length > 0) {
          // Saved project no longer available, select first one
          setCurrentProject(fetchedProjects[0])
        }
      } else if (fetchedProjects.length > 0) {
        // No saved project, select first one
        setCurrentProject(fetchedProjects[0])
      }
    } catch (err) {
      console.error('Failed to fetch projects:', err)
      setError('Failed to load projects')
    } finally {
      setIsLoading(false)
    }
  }, [isAuthenticated, setCurrentProject])

  const createProject = useCallback(async (name: string, description?: string): Promise<Project> => {
    const newProject = await projectService.createProject({
      project_name: name,
      project_desc: description,
    })
    
    // Add to projects list
    setProjects((prev: Project[]) => [newProject, ...prev])
    
    // If no current project, set this as current
    if (!currentProject) {
      setCurrentProject(newProject)
    }
    
    return newProject
  }, [currentProject, setCurrentProject])

  // Fetch projects when authentication status changes
  useEffect(() => {
    if (!authLoading) {
      refreshProjects()
    }
  }, [authLoading, isAuthenticated, refreshProjects])

  const value: ProjectContextType = {
    projects,
    currentProject,
    isLoading,
    error,
    setCurrentProject,
    refreshProjects,
    createProject,
  }

  return (
    <ProjectContext.Provider value={value}>{children}</ProjectContext.Provider>
  )
}
