import { useEffect, useState, useCallback, useRef } from 'react'
import { useNavigate, useSearchParams } from 'react-router-dom'
import { X, RotateCcw, Play, FileUp } from 'lucide-react'
import { PageMeta } from '@/components/common/PageMeta'
import { Button } from '@/components/ui/Button'
import { FlowIllustration } from '@/components/common/EmptyStateIllustrations'
import { treesApi } from '@/api/trees'
import { categoriesApi } from '@/api/categories'
import { foldersApi } from '@/api/folders'
import { sessionsApi } from '@/api/sessions'
import type { TreeListItem, CategoryListItem, FolderListItem, Session, IntakeFormField } from '@/types'
import { FolderEditModal } from '@/components/library/FolderEditModal'
import { ForkModal } from '@/components/library/ForkModal'
import { ExportFlowModal } from '@/components/library/ExportFlowModal'
import { ImportFlowModal } from '@/components/library/ImportFlowModal'
import { PrepareSessionModal } from '@/components/procedural/PrepareSessionModal'
import { accountsApi } from '@/api/accounts'
import { ConfirmDialog } from '@/components/common/ConfirmDialog'
import { TreeGridView } from '@/components/library/TreeGridView'
import { TreeListView } from '@/components/library/TreeListView'
import { TreeTableView } from '@/components/library/TreeTableView'
import { ViewToggle } from '@/components/library/ViewToggle'
import { SortDropdown } from '@/components/library/SortDropdown'
import { cn, safeGetItem } from '@/lib/utils'
import { getSessionResumePath, getTreeNavigatePath } from '@/lib/routing'
import { usePermissions } from '@/hooks/usePermissions'
import { useUserPreferencesStore } from '@/store/userPreferencesStore'
import { useCachedQuota } from '@/hooks/useCachedQuota'
import { CreateFlowDropdown } from '@/components/common/CreateFlowDropdown'
import { Spinner } from '@/components/common/Spinner'
import { EmptyState } from '@/components/common/EmptyState'
import { toast } from '@/lib/toast'

export function TreeLibraryPage() {
  const { canCreateTrees } = usePermissions()
  const navigate = useNavigate()
  const [searchParams] = useSearchParams()
  const [trees, setTrees] = useState<TreeListItem[]>([])
  const [categories, setCategories] = useState<CategoryListItem[]>([])
  const [folders, setFolders] = useState<FolderListItem[]>([])
  const urlCategory = searchParams.get('category') || ''
  const urlTags = searchParams.get('tags')
  const [selectedCategoryId, setSelectedCategoryId] = useState<string>(urlCategory)
  const [selectedTags, setSelectedTags] = useState<string[]>(urlTags ? urlTags.split(',') : [])
  const [selectedFolderId, setSelectedFolderId] = useState<string | null>(null)
  const [searchQuery, setSearchQuery] = useState('')
  const [isLoading, setIsLoading] = useState(true)
  // Read type filter from URL query params (e.g. /trees?type=procedural)
  const urlType = searchParams.get('type')
  const [typeFilter, setTypeFilter] = useState<'all' | 'troubleshooting' | 'procedural' | 'maintenance'>(
    urlType === 'troubleshooting' || urlType === 'procedural' || urlType === 'maintenance' ? urlType : 'all'
  )

  // Sync filters when URL changes (e.g. clicking sidebar categories/tags or nav sub-items)
  useEffect(() => {
    const t = searchParams.get('type')
    if (t === 'troubleshooting' || t === 'procedural' || t === 'maintenance') {
      setTypeFilter(t)
    } else {
      setTypeFilter('all')
    }
    setSelectedCategoryId(searchParams.get('category') || '')
    const tagsParam = searchParams.get('tags')
    setSelectedTags(tagsParam ? tagsParam.split(',') : [])
  }, [searchParams])

  // View preferences from store
  const { treeLibraryView, setTreeLibraryView, treeLibrarySortBy, setTreeLibrarySortBy } =
    useUserPreferencesStore()

  // Folder modal state
  const [folderModalOpen, setFolderModalOpen] = useState(false)
  const [editingFolder, setEditingFolder] = useState<FolderListItem | null>(null)
  const [newFolderParentId, setNewFolderParentId] = useState<string | null>(null)

  // Delete confirmation state
  const [treeToDelete, setTreeToDelete] = useState<TreeListItem | null>(null)
  const [showDeleteConfirm, setShowDeleteConfirm] = useState(false)
  const [isDeleting, setIsDeleting] = useState(false)

  // Fork modal state
  const [forkTarget, setForkTarget] = useState<TreeListItem | null>(null)

  // Import/Export modal state
  const [showImportModal, setShowImportModal] = useState(false)
  const [exportTarget, setExportTarget] = useState<TreeListItem | null>(null)

  // Prepare session modal state
  const [prepareTarget, setPrepareTarget] = useState<{
    tree: TreeListItem
    intakeFields: IntakeFormField[]
    teamMembers: { id: string; name: string; email: string }[]
  } | null>(null)

  // AI builder state

  const { aiEnabled } = useCachedQuota()

  // Repeat Last Session
  const lastSessionData = (() => {
    const raw = safeGetItem('last-session')
    if (!raw) return null
    try { return JSON.parse(raw) as { tree_id: string; tree_name: string; client_name: string; ticket_number: string; tree_type?: string } }
    catch { return null }
  })()

  // Incomplete sessions for auto-recovery
  const [incompleteSessions, setIncompleteSessions] = useState<Session[]>([])
  const [dismissedSessionIds, setDismissedSessionIds] = useState<Set<string>>(() => {
    try {
      const raw = sessionStorage.getItem('dismissed-sessions')
      return raw ? new Set(JSON.parse(raw) as string[]) : new Set()
    } catch { return new Set() }
  })

  const loadFolders = useCallback(async () => {
    try {
      const foldersData = await foldersApi.list()
      setFolders(foldersData)
    } catch (err) {
      console.error('Failed to load folders:', err)
    }
  }, [])

  // Load incomplete sessions on mount
  useEffect(() => {
    sessionsApi.list({ completed: false, size: 5 })
      .then(setIncompleteSessions)
      .catch((err) => console.error('Failed to load incomplete sessions:', err))
  }, [])

  const dismissSession = (sessionId: string) => {
    const next = new Set(dismissedSessionIds)
    next.add(sessionId)
    setDismissedSessionIds(next)
    try { sessionStorage.setItem('dismissed-sessions', JSON.stringify([...next])) } catch { /* */ }
  }

  const visibleIncompleteSessions = incompleteSessions.filter(s => !dismissedSessionIds.has(s.id))

  const formatTimeAgo = (dateString: string) => {
    const diff = Math.floor((Date.now() - new Date(dateString).getTime()) / 1000)
    if (diff < 60) return 'just now'
    if (diff < 3600) return `${Math.floor(diff / 60)} min ago`
    if (diff < 86400) return `${Math.floor(diff / 3600)} hr ago`
    return `${Math.floor(diff / 86400)} days ago`
  }

  // Load categories once on mount (they rarely change)
  useEffect(() => {
    categoriesApi.list()
      .then(setCategories)
      .catch((err) => console.error('Failed to load categories:', err))
  }, [])

  // Request ID ref to discard stale responses when filters change rapidly
  const loadTreesRequestId = useRef(0)

  const loadTrees = useCallback(async () => {
    const requestId = ++loadTreesRequestId.current
    setIsLoading(true)
    try {
      const treesData = await treesApi.list({
        tree_type: typeFilter !== 'all' ? typeFilter : undefined,
        category_id: selectedCategoryId || undefined,
        tags: selectedTags.length > 0 ? selectedTags.join(',') : undefined,
        folder_id: selectedFolderId || undefined,
        sort_by: treeLibrarySortBy,
      })
      if (requestId !== loadTreesRequestId.current) return
      setTrees(treesData)
    } catch (err) {
      if (requestId !== loadTreesRequestId.current) return
      toast.error('Failed to load flows')
      console.error(err)
    } finally {
      if (requestId === loadTreesRequestId.current) setIsLoading(false)
    }
  }, [selectedCategoryId, selectedTags, selectedFolderId, treeLibrarySortBy, typeFilter])

  // Load trees when filters change
  useEffect(() => {
    loadTrees()
  }, [loadTrees])

  // Load folders on mount and listen for changes
  useEffect(() => {
    loadFolders()
    const handleFolderChange = () => loadFolders()
    window.addEventListener('folder-changed', handleFolderChange)
    return () => window.removeEventListener('folder-changed', handleFolderChange)
  }, [loadFolders])

  const handleSearch = async () => {
    if (!searchQuery.trim()) {
      loadTrees()
      return
    }
    setIsLoading(true)
    try {
      const results = await treesApi.search(searchQuery)
      setTrees(results)
    } catch (err) {
      toast.error('Failed to search flows')
      console.error(err)
    } finally {
      setIsLoading(false)
    }
  }

  const handleTagClick = (tag: string) => {
    if (!selectedTags.includes(tag)) {
      setSelectedTags([...selectedTags, tag])
    }
  }

  const removeTagFilter = (tag: string) => {
    setSelectedTags(selectedTags.filter((t) => t !== tag))
  }

  const clearAllFilters = () => {
    setSelectedCategoryId('')
    setSelectedTags([])
    setSelectedFolderId(null)
    setSearchQuery('')
  }

  const handleStartSession = (treeId: string, treeType?: string) => {
    navigate(getTreeNavigatePath(treeId, treeType))
  }

  const handleCreateFolder = (parentId?: string | null) => {
    setEditingFolder(null)
    setNewFolderParentId(parentId || null)
    setFolderModalOpen(true)
  }

  const handleDeleteTree = async () => {
    if (!treeToDelete) return
    setIsDeleting(true)
    try {
      await treesApi.delete(treeToDelete.id)
      setTrees(trees.filter((t) => t.id !== treeToDelete.id))
      window.dispatchEvent(new Event('folder-changed'))
      toast.success(`"${treeToDelete.name}" deleted successfully`)
    } catch (err) {
      console.error('Failed to delete flow:', err)
      toast.error('Failed to delete flow')
    } finally {
      setIsDeleting(false)
      setShowDeleteConfirm(false)
      setTreeToDelete(null)
    }
  }

  const handleForkTree = (treeId: string) => {
    const tree = trees.find((t) => t.id === treeId)
    if (tree) setForkTarget(tree)
  }

  const handleExportTree = (treeId: string) => {
    const tree = trees.find((t) => t.id === treeId)
    if (tree) setExportTarget(tree)
  }

  const handlePrepareSession = async (tree: TreeListItem) => {
    try {
      const [treeDetail, members] = await Promise.all([
        treesApi.get(tree.id),
        accountsApi.getMembers().catch(() => []),
      ])
      setPrepareTarget({
        tree,
        intakeFields: treeDetail.intake_form || [],
        teamMembers: members
          .filter(m => m.is_active)
          .map(m => ({ id: m.id, name: m.name, email: m.email })),
      })
    } catch {
      toast.error('Failed to load flow details')
    }
  }

  const hasActiveFilters =
    selectedCategoryId || selectedTags.length > 0 || searchQuery || selectedFolderId

  return (
    <div className="overflow-y-auto h-full">
    <PageMeta title="Flow Library" />
    <div className="min-h-full">
      <div className="container mx-auto px-4 py-6 sm:px-6 sm:py-8">
          <div className="mb-6 flex flex-col gap-4 sm:mb-8 sm:flex-row sm:items-start sm:justify-between">
            <div>
              <h1 className="text-2xl font-bold font-heading text-foreground sm:text-3xl">
                {typeFilter === 'procedural' ? 'Projects' : typeFilter === 'troubleshooting' ? 'Troubleshooting Flows' : typeFilter === 'maintenance' ? 'Maintenance Flows' : 'Flow Library'}
              </h1>
              <p className="mt-2 text-muted-foreground">
                {typeFilter === 'procedural'
                  ? 'Step-by-step projects and runbooks'
                  : typeFilter === 'troubleshooting'
                    ? 'Branching decision flows for troubleshooting'
                    : typeFilter === 'maintenance'
                      ? 'Scheduled maintenance procedures run across targets'
                      : 'Browse and start troubleshooting flows and projects'}
              </p>
            </div>
            {canCreateTrees && (
              <div className="flex items-center gap-2">
                <Button
                  variant="secondary"
                  onClick={() => setShowImportModal(true)}
                >
                  <FileUp className="h-4 w-4" />
                  Import
                </Button>
                <CreateFlowDropdown
                  aiEnabled={aiEnabled}

                  label="Create New"
                />
              </div>
            )}
          </div>

          {/* Search and Filter */}
          <div className="mb-4 space-y-4">
            <div className="flex flex-col gap-4 sm:flex-row">
              <div className="flex flex-1 gap-2">
                <input
                  type="text"
                  placeholder="Search flows..."
                  value={searchQuery}
                  onChange={(e) => setSearchQuery(e.target.value)}
                  onKeyDown={(e) => e.key === 'Enter' && handleSearch()}
                  className={cn(
                    'flex-1 rounded-md border border-border bg-card px-3 py-2',
                    'text-foreground placeholder:text-muted-foreground',
                    'focus:border-primary focus:outline-hidden focus:ring-1 focus:ring-primary/20'
                  )}
                />
                <Button onClick={handleSearch}>
                  Search
                </Button>
              </div>

              <select
                value={selectedCategoryId}
                onChange={(e) => setSelectedCategoryId(e.target.value)}
                aria-label="Filter by category"
                className={cn(
                  'rounded-md border border-border bg-card px-3 py-2',
                  'text-foreground focus:border-primary focus:outline-hidden focus:ring-1 focus:ring-primary/20'
                )}
              >
                <option value="">All Categories</option>
                {categories.map((cat) => (
                  <option key={cat.id} value={cat.id}>
                    {cat.name} ({cat.tree_count})
                  </option>
                ))}
              </select>
            </div>

            {/* View Controls */}
            <div className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
              {/* Type filter tabs */}
              <div className="flex rounded-lg border border-border p-0.5">
                {(['all', 'troubleshooting', 'procedural', 'maintenance'] as const).map((t) => (
                    <button
                      key={t}
                      onClick={() => setTypeFilter(t)}
                      className={cn(
                        'rounded-md px-3 py-1 text-xs font-medium transition-colors',
                        typeFilter === t
                          ? 'bg-accent text-foreground'
                          : 'text-muted-foreground hover:text-foreground'
                      )}
                    >
                      {t === 'all' ? 'All' : t === 'troubleshooting' ? 'Troubleshooting' : t === 'procedural' ? 'Projects' : 'Maintenance'}
                    </button>
                  ))}
              </div>

              {/* Right controls: sort + view toggle */}
              <div className="flex items-center gap-2">
                <SortDropdown value={treeLibrarySortBy} onChange={setTreeLibrarySortBy} />
                <ViewToggle view={treeLibraryView} onChange={setTreeLibraryView} />
              </div>
            </div>
          </div>

          {/* Active Filters */}
          {hasActiveFilters && (
            <div className="mb-6 flex flex-wrap items-center gap-2">
              <span className="text-sm text-muted-foreground">Filters:</span>
              {selectedFolderId && (
                <span className="inline-flex items-center gap-1 rounded-full bg-accent px-3 py-1 text-sm text-foreground">
                  Folder
                  <button
                    onClick={() => setSelectedFolderId(null)}
                    className="rounded-full p-0.5 hover:bg-accent"
                  >
                    <X className="h-3 w-3" />
                  </button>
                </span>
              )}
              {selectedCategoryId && (
                <span className="inline-flex items-center gap-1 rounded-full bg-accent px-3 py-1 text-sm text-foreground">
                  {categories.find((c) => c.id === selectedCategoryId)?.name}
                  <button
                    onClick={() => setSelectedCategoryId('')}
                    className="rounded-full p-0.5 hover:bg-accent"
                  >
                    <X className="h-3 w-3" />
                  </button>
                </span>
              )}
              {selectedTags.map((tag) => (
                <span
                  key={tag}
                  className="inline-flex items-center gap-1 rounded-full bg-accent px-3 py-1 text-sm text-foreground"
                >
                  {tag}
                  <button
                    onClick={() => removeTagFilter(tag)}
                    className="rounded-full p-0.5 hover:bg-accent"
                  >
                    <X className="h-3 w-3" />
                  </button>
                </span>
              ))}
              <button
                onClick={clearAllFilters}
                className="text-sm text-muted-foreground hover:text-foreground"
              >
                Clear all
              </button>
            </div>
          )}

          {/* Incomplete Session Recovery */}
          {visibleIncompleteSessions.length > 0 && (
            <div className="mb-6 space-y-2">
              {visibleIncompleteSessions.map(s => (
                <div key={s.id} className="bg-card border border-border flex items-center justify-between rounded-xl p-4">
                  <div className="min-w-0 flex-1">
                    <p className="truncate font-medium text-foreground">
                      {s.tree_snapshot?.name || 'Unknown tree'}
                    </p>
                    <p className="text-sm text-muted-foreground">
                      {s.client_name && `${s.client_name} · `}
                      {s.started_at ? `Started ${formatTimeAgo(s.started_at)}` : 'Not started'}
                    </p>
                  </div>
                  <div className="flex items-center gap-2">
                    <Button
                      size="sm"
                      onClick={() => navigate(getSessionResumePath(s.tree_id, s.tree_snapshot?.tree_type), { state: { sessionId: s.id } })}
                    >
                      <Play className="h-3.5 w-3.5" />
                      Resume
                    </Button>
                    <button
                      onClick={() => dismissSession(s.id)}
                      className="rounded-md p-1.5 text-muted-foreground hover:bg-accent hover:text-foreground"
                    >
                      <X className="h-4 w-4" />
                    </button>
                  </div>
                </div>
              ))}
            </div>
          )}

          {/* Repeat Last Session */}
          {lastSessionData && (
            <div className="mb-6">
              <button
                onClick={() => navigate(getSessionResumePath(lastSessionData.tree_id, lastSessionData.tree_type), {
                  state: { prefillClientName: lastSessionData.client_name, prefillTicketNumber: lastSessionData.ticket_number },
                })}
                className={cn(
                  'flex items-center gap-2 rounded-lg border border-border px-4 py-2.5 text-sm text-muted-foreground',
                  'hover:border-border hover:bg-accent hover:text-foreground'
                )}
              >
                <RotateCcw className="h-4 w-4" />
                Repeat: {lastSessionData.tree_name}
                {lastSessionData.client_name && ` (${lastSessionData.client_name})`}
              </button>
            </div>
          )}

          {/* Loading State */}
          {isLoading ? (
            <div className="flex justify-center py-12">
              <Spinner />
            </div>
          ) : trees.length === 0 ? (
            (searchQuery || hasActiveFilters) ? (
              <EmptyState
                title="No flows match your filters"
                description="Try adjusting your search or filters."
                action={
                  <Button variant="secondary" onClick={clearAllFilters}>
                    Clear Filters
                  </Button>
                }
              />
            ) : (
              <EmptyState
                illustration={<FlowIllustration />}
                title="Build your first troubleshooting flow"
                description="Flows guide your team through proven resolution paths, capturing every decision along the way."
                action={
                  canCreateTrees ? (
                    <CreateFlowDropdown aiEnabled={aiEnabled} label="Create a Flow" />
                  ) : undefined
                }
                learnMoreLink="/guides/creating-flows"
              />
            )
          ) : (
            <>
              {treeLibraryView === 'grid' && (
                <TreeGridView
                  trees={trees}
                  onStartSession={handleStartSession}
                  onPrepareSession={handlePrepareSession}
                  onTagClick={handleTagClick}
                  onFolderCreated={handleCreateFolder}
                  onDeleteTree={(tree) => {
                    setTreeToDelete(tree)
                    setShowDeleteConfirm(true)
                  }}
                  onForkTree={handleForkTree}
                  onExportTree={handleExportTree}
                />
              )}
              {treeLibraryView === 'list' && (
                <TreeListView
                  trees={trees}
                  onStartSession={handleStartSession}
                  onPrepareSession={handlePrepareSession}
                  onTagClick={handleTagClick}
                  onFolderCreated={handleCreateFolder}
                  onDeleteTree={(tree) => {
                    setTreeToDelete(tree)
                    setShowDeleteConfirm(true)
                  }}
                  onForkTree={handleForkTree}
                  onExportTree={handleExportTree}
                />
              )}
              {treeLibraryView === 'table' && (
                <TreeTableView
                  trees={trees}
                  onStartSession={handleStartSession}
                  onPrepareSession={handlePrepareSession}
                  onTagClick={handleTagClick}
                  onFolderCreated={handleCreateFolder}
                  onDeleteTree={(tree) => {
                    setTreeToDelete(tree)
                    setShowDeleteConfirm(true)
                  }}
                  onSortChange={(sortBy) => {
                    setTreeLibrarySortBy(
                      sortBy as 'usage_count' | 'updated_at' | 'created_at' | 'name' | 'name_desc' | 'version'
                    )
                  }}
                  onForkTree={handleForkTree}
                  onExportTree={handleExportTree}
                />
              )}
            </>
          )}
      </div>

      {/* Folder Edit Modal */}
      <FolderEditModal
        folder={editingFolder}
        parentId={newFolderParentId}
        folders={folders}
        isOpen={folderModalOpen}
        onClose={() => {
          setFolderModalOpen(false)
          setNewFolderParentId(null)
        }}
        onSave={loadTrees}
      />

      {/* Delete Confirmation */}
      <ConfirmDialog
        isOpen={showDeleteConfirm}
        onClose={() => {
          setShowDeleteConfirm(false)
          setTreeToDelete(null)
        }}
        onConfirm={handleDeleteTree}
        title="Delete Flow"
        message={`Are you sure you want to delete "${treeToDelete?.name}"? This action can be undone by an administrator.`}
        confirmLabel="Delete"
        confirmVariant="destructive"
        isLoading={isDeleting}
      />


      {forkTarget && (
        <ForkModal
          treeId={forkTarget.id}
          treeName={forkTarget.name}
          onClose={() => setForkTarget(null)}
        />
      )}

      {exportTarget && (
        <ExportFlowModal
          treeId={exportTarget.id}
          treeName={exportTarget.name}
          onClose={() => setExportTarget(null)}
        />
      )}

      {showImportModal && (
        <ImportFlowModal
          onClose={() => { setShowImportModal(false); loadTrees() }}
        />
      )}

      {prepareTarget && (
        <PrepareSessionModal
          isOpen
          onClose={() => setPrepareTarget(null)}
          treeId={prepareTarget.tree.id}
          treeName={prepareTarget.tree.name}
          intakeFields={prepareTarget.intakeFields}
          teamMembers={prepareTarget.teamMembers}
          onPrepared={() => setPrepareTarget(null)}
        />
      )}
    </div>
    </div>
  )
}

export default TreeLibraryPage
