import { useEffect, useState, useRef } from 'react'
import { useParams, useNavigate } from 'react-router-dom'
import { ChevronLeft, ChevronRight, ListOrdered, Settings2, X } from 'lucide-react'
import { treesApi } from '@/api/trees'
import { sessionsApi } from '@/api/sessions'
import type { Tree, Session, ProceduralStep, DecisionRecord } from '@/types'
import { IntakeFormModal } from '@/components/procedural/IntakeFormModal'
import { StepChecklist } from '@/components/procedural/StepChecklist'
import { StepDetail } from '@/components/procedural/StepDetail'
import { ProgressBar } from '@/components/procedural/ProgressBar'
import { CompletionSummary } from '@/components/procedural/CompletionSummary'
import { cn } from '@/lib/utils'
import { toast } from '@/lib/toast'

interface StepState {
  notes: string
  verificationValue: string
  completedAt: string | null
}

export function ProceduralNavigationPage() {
  const { id: treeId } = useParams<{ id: string }>()
  const navigate = useNavigate()

  const [tree, setTree] = useState<Tree | null>(null)
  const [session, setSession] = useState<Session | null>(null)
  const [isLoading, setIsLoading] = useState(true)
  const [showIntakeForm, setShowIntakeForm] = useState(false)
  const [sessionVariables, setSessionVariables] = useState<Record<string, string>>({})
  const [currentStepIndex, setCurrentStepIndex] = useState(0)
  const [stepStates, setStepStates] = useState<Map<string, StepState>>(new Map())
  const [isComplete, setIsComplete] = useState(false)
  const [completedAt, setCompletedAt] = useState<string>('')
  const [sidebarOpen, setSidebarOpen] = useState(true)
  const [paramsOpen, setParamsOpen] = useState(false)
  const [elapsedMinutes, setElapsedMinutes] = useState(0)
  const timerRef = useRef<ReturnType<typeof setInterval> | null>(null)

  // Get procedural steps from tree
  const getSteps = (): ProceduralStep[] => {
    if (!tree) return []
    const structure = tree.tree_structure as unknown as { steps?: ProceduralStep[] }
    return structure.steps || []
  }

  const steps = getSteps()
  const procedureSteps = steps.filter((s) => s.type === 'procedure_step')
  const completedStepIds = new Set(
    Array.from(stepStates.entries())
      .filter(([, state]) => state.completedAt)
      .map(([id]) => id)
  )

  const estimatedTotalMinutes = procedureSteps.reduce(
    (sum, step) => sum + (step.estimated_minutes || 0),
    0
  )

  // Load tree
  useEffect(() => {
    if (!treeId) return
    loadTree(treeId)
    return () => {
      if (timerRef.current) clearInterval(timerRef.current)
    }
  }, [treeId])

  // Parse backend timestamp — ensure UTC if no timezone info
  const parseTimestamp = (ts: string) => {
    if (!ts.endsWith('Z') && !ts.includes('+') && !/\d{2}:\d{2}$/.test(ts.slice(-5))) {
      return new Date(ts + 'Z')
    }
    return new Date(ts)
  }

  // Elapsed time timer
  useEffect(() => {
    if (session && !isComplete) {
      const calcElapsed = () => {
        const start = parseTimestamp(session.started_at).getTime()
        setElapsedMinutes(Math.max(0, Math.floor((Date.now() - start) / 60000)))
      }
      calcElapsed()
      timerRef.current = setInterval(calcElapsed, 30000)
    }
    return () => {
      if (timerRef.current) clearInterval(timerRef.current)
    }
  }, [session, isComplete])

  const loadTree = async (id: string) => {
    setIsLoading(true)
    try {
      const treeData = await treesApi.get(id)
      if (treeData.tree_type !== 'procedural') {
        navigate(`/trees/${id}/navigate`, { replace: true })
        return
      }
      setTree(treeData)

      // Check if intake form exists
      if (treeData.intake_form && treeData.intake_form.length > 0) {
        setShowIntakeForm(true)
      } else {
        await startSession(id, {})
      }
    } catch {
      toast.error('Failed to load procedure')
      navigate('/my-trees')
    } finally {
      setIsLoading(false)
    }
  }

  const startSession = async (id: string, variables: Record<string, string>) => {
    try {
      const newSession = await sessionsApi.create({
        tree_id: id,
        session_variables: Object.keys(variables).length > 0 ? variables : undefined,
      })
      setSession(newSession)
      setSessionVariables(variables)
      setShowIntakeForm(false)

      // Initialize step states
      const initialStates = new Map<string, StepState>()
      const allSteps = getStepsFromTree(tree!)
      for (const step of allSteps) {
        initialStates.set(step.id, { notes: '', verificationValue: '', completedAt: null })
      }
      setStepStates(initialStates)
    } catch {
      toast.error('Failed to start session')
    }
  }

  const getStepsFromTree = (t: Tree): ProceduralStep[] => {
    const structure = t.tree_structure as unknown as { steps?: ProceduralStep[] }
    return structure.steps || []
  }

  const handleIntakeSubmit = async (variables: Record<string, string>) => {
    if (!treeId) return
    await startSession(treeId, variables)
  }

  const handleMarkComplete = async () => {
    if (!session || procedureSteps.length === 0) return

    const currentStep = procedureSteps[currentStepIndex]
    if (!currentStep) return

    const now = new Date().toISOString()

    // Update step state
    setStepStates((prev) => {
      const next = new Map(prev)
      const existing = next.get(currentStep.id) || { notes: '', verificationValue: '', completedAt: null }
      next.set(currentStep.id, { ...existing, completedAt: now })
      return next
    })

    // Create a decision record for this step
    const stepState = stepStates.get(currentStep.id)
    const decision: DecisionRecord = {
      node_id: currentStep.id,
      question: currentStep.title,
      answer: 'completed',
      action_performed: currentStep.description || null,
      notes: stepState?.notes || null,
      command_output: stepState?.verificationValue || null,
      automation_used: false,
      timestamp: now,
      entered_at: null,
      exited_at: now,
      duration_seconds: null,
      attachments: [],
    }

    try {
      const updatedDecisions = [...(session.decisions || []), decision]
      await sessionsApi.update(session.id, {
        decisions: updatedDecisions,
        path_taken: [...(session.path_taken || []), currentStep.id],
      })

      setSession((prev) => prev ? {
        ...prev,
        decisions: updatedDecisions,
        path_taken: [...(prev.path_taken || []), currentStep.id],
      } : prev)

      // Move to next step or complete
      if (currentStepIndex >= procedureSteps.length - 1) {
        // Last step — complete the procedure
        const completedTime = new Date().toISOString()
        await sessionsApi.complete(session.id, {
          outcome: 'resolved',
          outcome_notes: `Procedure completed. ${procedureSteps.length} steps finished.`,
        })
        setCompletedAt(completedTime)
        setIsComplete(true)
      } else {
        setCurrentStepIndex(currentStepIndex + 1)
      }
    } catch {
      toast.error('Failed to save progress')
    }
  }

  const handleStepNotesChange = (notes: string) => {
    const currentStep = procedureSteps[currentStepIndex]
    if (!currentStep) return
    setStepStates((prev) => {
      const next = new Map(prev)
      const existing = next.get(currentStep.id) || { notes: '', verificationValue: '', completedAt: null }
      next.set(currentStep.id, { ...existing, notes })
      return next
    })
  }

  const handleVerificationChange = (value: string) => {
    const currentStep = procedureSteps[currentStepIndex]
    if (!currentStep) return
    setStepStates((prev) => {
      const next = new Map(prev)
      const existing = next.get(currentStep.id) || { notes: '', verificationValue: '', completedAt: null }
      next.set(currentStep.id, { ...existing, verificationValue: value })
      return next
    })
  }

  // Loading state
  if (isLoading) {
    return (
      <div className="flex min-h-[50vh] items-center justify-center">
        <div className="h-8 w-8 animate-spin rounded-full border-4 border-white/20 border-t-white" />
      </div>
    )
  }

  // Intake form modal
  if (showIntakeForm && tree) {
    return (
      <IntakeFormModal
        isOpen={true}
        fields={tree.intake_form || []}
        treeName={tree.name}
        onSubmit={handleIntakeSubmit}
        onCancel={() => navigate('/my-trees')}
      />
    )
  }

  // Completion summary
  if (isComplete && tree && session) {
    return (
      <div className="container mx-auto px-4 py-8 sm:px-6">
        <CompletionSummary
          treeName={tree.name}
          steps={steps}
          completions={new Map(
            Array.from(stepStates.entries())
              .filter(([, s]) => s.completedAt)
              .map(([id, s]) => [id, {
                stepId: id,
                notes: s.notes,
                verificationValue: s.verificationValue,
                completedAt: s.completedAt!,
              }])
          )}
          variables={sessionVariables}
          startedAt={session.started_at}
          completedAt={completedAt}
          onExport={() => navigate(`/sessions/${session.id}`)}
          onClose={() => navigate('/my-trees')}
        />
      </div>
    )
  }

  // No session yet
  if (!session || !tree) return null

  const currentStep = procedureSteps[currentStepIndex]
  const currentStepState = currentStep ? stepStates.get(currentStep.id) : undefined

  return (
    <div className="flex h-[calc(100vh-4rem)] flex-col">
      {/* Top bar */}
      <div className="border-b border-white/[0.06] px-4 py-3 sm:px-6">
        <div className="flex items-center justify-between gap-4">
          <div className="flex items-center gap-3">
            <button
              onClick={() => setSidebarOpen(!sidebarOpen)}
              className="rounded-md p-1.5 text-white/40 hover:bg-white/10 hover:text-white lg:hidden"
            >
              {sidebarOpen ? <ChevronLeft className="h-4 w-4" /> : <ChevronRight className="h-4 w-4" />}
            </button>
            <ListOrdered className="h-5 w-5 text-white/40" />
            <h1 className="text-sm font-semibold text-white sm:text-base">{tree.name}</h1>
          </div>
        </div>
        <div className="mt-2">
          <ProgressBar
            currentStep={completedStepIds.size}
            totalSteps={procedureSteps.length}
            elapsedMinutes={elapsedMinutes}
            estimatedTotalMinutes={estimatedTotalMinutes || undefined}
          />
        </div>
      </div>

      {/* Main content */}
      <div className="flex min-h-0 flex-1">
        {/* Left sidebar - step checklist */}
        <div
          className={cn(
            'border-r border-white/[0.06] bg-black/30 transition-all duration-200',
            sidebarOpen ? 'w-72 p-3' : 'w-0 overflow-hidden p-0'
          )}
        >
          {sidebarOpen && (
            <>
              <StepChecklist
                steps={steps}
                currentStepIndex={currentStepIndex}
                completedStepIds={completedStepIds}
                onStepClick={setCurrentStepIndex}
              />

              {/* View Parameters button */}
              {Object.keys(sessionVariables).length > 0 && (
                <div className="mt-3 border-t border-white/[0.06] pt-3">
                  <button
                    onClick={() => setParamsOpen(true)}
                    className="flex w-full items-center gap-2 rounded-lg border border-white/10 px-3 py-2 text-xs text-white/40 hover:bg-white/[0.06] hover:text-white/60"
                  >
                    <Settings2 className="h-3.5 w-3.5" />
                    View Parameters ({Object.keys(sessionVariables).length})
                  </button>
                </div>
              )}
            </>
          )}
        </div>

        {/* Right panel - step detail */}
        <div className="min-h-0 flex-1 overflow-y-auto p-4 sm:p-6">
          {currentStep && (
            <StepDetail
              step={currentStep}
              stepNumber={currentStepIndex + 1}
              totalSteps={procedureSteps.length}
              variables={sessionVariables}
              notes={currentStepState?.notes || ''}
              onNotesChange={handleStepNotesChange}
              verificationValue={currentStepState?.verificationValue || ''}
              onVerificationChange={handleVerificationChange}
              isCompleted={completedStepIds.has(currentStep.id)}
              onMarkComplete={handleMarkComplete}
              isLast={currentStepIndex === procedureSteps.length - 1}
            />
          )}
        </div>
      </div>

      {/* Parameters popover */}
      {paramsOpen && (
        <div className="fixed inset-0 z-50 flex items-center justify-center">
          <div
            className="absolute inset-0 bg-black/60 backdrop-blur-sm"
            onClick={() => setParamsOpen(false)}
          />
          <div className="relative w-full max-w-md rounded-2xl border border-white/10 bg-black/95 shadow-2xl backdrop-blur-sm">
            <div className="flex items-center justify-between border-b border-white/[0.06] px-5 py-4">
              <h3 className="text-sm font-semibold text-white">Project Parameters</h3>
              <button
                onClick={() => setParamsOpen(false)}
                className="rounded-lg p-1 text-white/40 hover:bg-white/10 hover:text-white"
              >
                <X className="h-4 w-4" />
              </button>
            </div>
            <div className="max-h-[60vh] overflow-y-auto p-5">
              <div className="space-y-2">
                {Object.entries(sessionVariables).map(([key, value]) => (
                  <div key={key} className="flex items-baseline justify-between gap-4 rounded-lg bg-white/[0.03] px-3 py-2">
                    <span className="text-xs font-medium text-white/40">{key.replace(/_/g, ' ')}</span>
                    <span className="text-right text-sm text-white/70">{value || 'N/A'}</span>
                  </div>
                ))}
              </div>
            </div>
          </div>
        </div>
      )}
    </div>
  )
}

export default ProceduralNavigationPage
