import { useState, useCallback } from 'react'
import { aiSessionsApi } from '@/api'
import type {
  AISessionCreateRequest,
  AISessionCreateResponse,
  AISessionDetail,
  AISessionStepResponse,
  StepResponseRequest,
  StepResponseResponse,
  ResolveSessionRequest,
  EscalateSessionRequest,
  SessionDocumentation,
  StatusUpdateRequest,
  StatusUpdateResponse,
} from '@/types/ai-session'
import { toast } from '@/lib/toast'

export interface UseFlowPilotSession {
  // State
  session: AISessionDetail | null
  currentStep: AISessionStepResponse | null
  allSteps: AISessionStepResponse[]
  isLoading: boolean
  isProcessing: boolean
  error: string | null

  // Actions
  startSession: (intake: AISessionCreateRequest) => Promise<void>
  respondToStep: (response: StepResponseRequest) => Promise<void>
  resolveSession: (data: ResolveSessionRequest) => Promise<SessionDocumentation | null>
  escalateSession: (data: EscalateSessionRequest) => Promise<SessionDocumentation | null>
  pauseSession: () => Promise<void>
  resumeOwnSession: () => Promise<void>
  abandonSession: () => Promise<void>
  rateSession: (rating: number, feedback?: string) => Promise<void>
  generateStatusUpdate: (data: StatusUpdateRequest) => Promise<StatusUpdateResponse>
  loadSession: (sessionId: string) => Promise<void>

  // Derived
  isActive: boolean
  canResolve: boolean
  canEscalate: boolean

  // Post-close
  documentation: SessionDocumentation | null
  psaPushStatus: string | null
  psaPushError: string | null
  memberMappingWarning: string | null
}

export function useFlowPilotSession(): UseFlowPilotSession {
  const [session, setSession] = useState<AISessionDetail | null>(null)
  const [currentStep, setCurrentStep] = useState<AISessionStepResponse | null>(null)
  const [allSteps, setAllSteps] = useState<AISessionStepResponse[]>([])
  const [isLoading, setIsLoading] = useState(false)
  const [isProcessing, setIsProcessing] = useState(false)
  const [error, setError] = useState<string | null>(null)
  const [documentation, setDocumentation] = useState<SessionDocumentation | null>(null)
  const [psaPushStatus, setPsaPushStatus] = useState<string | null>(null)
  const [psaPushError, setPsaPushError] = useState<string | null>(null)
  const [memberMappingWarning, setMemberMappingWarning] = useState<string | null>(null)

  const startSession = useCallback(async (intake: AISessionCreateRequest) => {
    setIsLoading(true)
    setError(null)
    try {
      const result: AISessionCreateResponse = await aiSessionsApi.createSession(intake)
      const firstStep = result.first_step

      setSession({
        id: result.session_id,
        session_type: 'guided',
        title: null,
        status: result.status,
        intake_type: intake.intake_type,
        intake_content: intake.intake_content,
        problem_summary: result.problem_summary,
        problem_domain: result.problem_domain,
        confidence_tier: result.confidence_tier,
        step_count: 1,
        session_rating: null,
        created_at: new Date().toISOString(),
        resolved_at: null,
        matched_flow_id: result.matched_flow_id,
        match_score: result.match_score,
        resolution_summary: null,
        resolution_action: null,
        escalation_reason: null,
        session_feedback: null,
        psa_ticket_id: intake.psa_ticket_id ?? null,
        psa_connection_id: intake.psa_connection_id ?? null,
        ticket_data: null,
        steps: [firstStep],
        conversation_messages: [],
        pending_task_lane: null,
        is_branching: false,
        active_branch_id: null,
      })
      setAllSteps([firstStep])
      setCurrentStep(firstStep)
    } catch (e: unknown) {
      // Prefer the backend's detail message over the generic axios status string
      const detail = (e as any)?.response?.data?.detail
      const message = typeof detail === 'string' ? detail : (e instanceof Error ? e.message : 'Failed to start session')
      setError(message)
      // Global axios interceptor already shows a toast for 5xx — skip duplicate
      if (!(e as any)?.response?.status || (e as any)?.response?.status < 500) {
        toast.error(message)
      }
    } finally {
      setIsLoading(false)
    }
  }, [])

  const respondToStep = useCallback(async (response: StepResponseRequest) => {
    if (!session) return
    setIsProcessing(true)
    setError(null)
    try {
      const result: StepResponseResponse = await aiSessionsApi.respondToStep(session.id, response)

      setSession(prev => prev ? {
        ...prev,
        status: result.status,
        confidence_tier: result.confidence_tier,
        step_count: prev.step_count + 1,
      } : null)

      if (result.next_step) {
        setAllSteps(prev => [...prev, result.next_step!])
        setCurrentStep(result.next_step)
      }
    } catch (e: unknown) {
      const message = e instanceof Error ? e.message : 'Failed to process response'
      setError(message)
      toast.error(message)
    } finally {
      setIsProcessing(false)
    }
  }, [session])

  const resolveSession = useCallback(async (data: ResolveSessionRequest): Promise<SessionDocumentation | null> => {
    if (!session) throw new Error('No active session')
    setIsProcessing(true)
    try {
      const result = await aiSessionsApi.resolveSession(session.id, data)
      setSession(prev => prev ? { ...prev, status: 'resolved' } : null)
      setDocumentation(result.documentation)
      setPsaPushStatus(result.psa_push_status)
      setPsaPushError(result.psa_push_error)
      setMemberMappingWarning(result.member_mapping_warning)
      setCurrentStep(null)
      toast.success('Session resolved')
      return result.documentation
    } catch (e: unknown) {
      const message = e instanceof Error ? e.message : 'Failed to resolve session'
      toast.error(message)
      throw e
    } finally {
      setIsProcessing(false)
    }
  }, [session])

  const escalateSession = useCallback(async (data: EscalateSessionRequest): Promise<SessionDocumentation | null> => {
    if (!session) throw new Error('No active session')
    setIsProcessing(true)
    try {
      const result = await aiSessionsApi.escalateSession(session.id, data)
      setSession(prev => prev ? { ...prev, status: 'requesting_escalation' } : null)
      setDocumentation(result.documentation)
      setPsaPushStatus(result.psa_push_status)
      setPsaPushError(result.psa_push_error)
      setMemberMappingWarning(result.member_mapping_warning)
      setCurrentStep(null)
      toast.success('Session escalated')
      return result.documentation
    } catch (e: unknown) {
      const message = e instanceof Error ? e.message : 'Failed to escalate session'
      toast.error(message)
      throw e
    } finally {
      setIsProcessing(false)
    }
  }, [session])

  const pauseSession = useCallback(async () => {
    if (!session) return
    try {
      await aiSessionsApi.pauseSession(session.id)
      setSession(prev => prev ? { ...prev, status: 'paused' } : null)
      toast.success('Session paused')
    } catch {
      toast.error('Failed to pause session')
    }
  }, [session])

  const resumeOwnSession = useCallback(async () => {
    if (!session) return
    try {
      await aiSessionsApi.resumeSession(session.id)
      setSession(prev => prev ? { ...prev, status: 'active' } : null)
      toast.success('Session resumed')
    } catch {
      toast.error('Failed to resume session')
    }
  }, [session])

  const abandonSession = useCallback(async () => {
    if (!session) return
    try {
      await aiSessionsApi.abandonSession(session.id)
      setSession(prev => prev ? { ...prev, status: 'abandoned' } : null)
      setCurrentStep(null)
      toast.success('Session closed')
    } catch {
      toast.error('Failed to close session')
    }
  }, [session])

  const rateSession = useCallback(async (rating: number, feedback?: string) => {
    if (!session) return
    try {
      await aiSessionsApi.rateSession(session.id, { rating, feedback })
      setSession(prev => prev ? { ...prev, session_rating: rating } : null)
      toast.success('Thanks for your feedback!')
    } catch {
      toast.error('Failed to submit rating')
    }
  }, [session])

  const generateStatusUpdate = useCallback(async (data: StatusUpdateRequest): Promise<StatusUpdateResponse> => {
    if (!session) throw new Error('No active session')
    try {
      return await aiSessionsApi.generateStatusUpdate(session.id, data)
    } catch (e: unknown) {
      const message = e instanceof Error ? e.message : 'Failed to generate status update'
      toast.error(message)
      throw e
    }
  }, [session])

  const loadSession = useCallback(async (sessionId: string) => {
    setIsLoading(true)
    setError(null)
    try {
      const detail = await aiSessionsApi.getSession(sessionId)
      setSession(detail)
      setAllSteps(detail.steps)
      // Set current step for active and paused sessions (paused can be resumed)
      setCurrentStep(
        detail.status === 'active' || detail.status === 'paused'
          ? detail.steps[detail.steps.length - 1] ?? null
          : null
      )

      if (detail.status === 'resolved' || detail.status === 'escalated') {
        const doc = await aiSessionsApi.getDocumentation(sessionId)
        setDocumentation(doc)
      }
    } catch (e: unknown) {
      const message = e instanceof Error ? e.message : 'Failed to load session'
      setError(message)
      toast.error(message)
    } finally {
      setIsLoading(false)
    }
  }, [])

  const isActive = session?.status === 'active'
  const canResolve = isActive && allSteps.length >= 1
  const canEscalate = isActive && allSteps.length >= 1

  return {
    session,
    currentStep,
    allSteps,
    isLoading,
    isProcessing,
    error,
    startSession,
    respondToStep,
    resolveSession,
    escalateSession,
    pauseSession,
    resumeOwnSession,
    abandonSession,
    rateSession,
    generateStatusUpdate,
    loadSession,
    isActive,
    canResolve,
    canEscalate,
    documentation,
    psaPushStatus,
    psaPushError,
    memberMappingWarning,
  }
}
