import { useState, useEffect, useRef, useCallback } from 'react'
import { Ticket, Search, AlertCircle, CheckCircle2, Hash, Loader2 } from 'lucide-react'
import { Modal } from '@/components/common/Modal'
import { Input } from '@/components/ui/Input'
import { Button } from '@/components/ui/Button'
import { cn } from '@/lib/utils'
import { integrationsApi, sessionPsaApi } from '@/api/integrations'
import type { PSATicketInfo, PSATicketSearchResult } from '@/types/integrations'

type Mode = 'search' | 'manual'

interface Props {
  open: boolean
  onClose: () => void
  /** Legacy session linking mode — pass sessionId + onLinked */
  sessionId?: string
  onLinked?: (ticketId: string, ticket: PSATicketInfo) => void
  /** Selection-only mode — pass onSelect instead. Returns selected ticket without linking. */
  onSelect?: (ticketId: string, ticket: PSATicketInfo) => void
}

export function TicketPickerModal({ open, onClose, sessionId, onLinked, onSelect }: Props) {
  const [mode, setMode] = useState<Mode>('search')

  // Search mode state
  const [searchQuery, setSearchQuery] = useState('')
  const [includeClosed, setIncludeClosed] = useState(false)
  const [searchResults, setSearchResults] = useState<PSATicketSearchResult[]>([])
  const [isSearching, setIsSearching] = useState(false)
  const [hasSearched, setHasSearched] = useState(false)

  // Manual mode state
  const [manualId, setManualId] = useState('')

  // Shared state
  const [selectedTicket, setSelectedTicket] = useState<PSATicketInfo | null>(null)
  const [selectedTicketId, setSelectedTicketId] = useState<string | null>(null)
  const [isLooking, setIsLooking] = useState(false)
  const [isLinking, setIsLinking] = useState(false)
  const [error, setError] = useState<string | null>(null)

  const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null)

  // Debounced search
  const performSearch = useCallback(async (query: string, closed: boolean) => {
    if (!query.trim()) {
      setSearchResults([])
      setHasSearched(false)
      return
    }

    setIsSearching(true)
    setError(null)
    try {
      const results = await integrationsApi.searchTickets({
        query: query.trim(),
        include_closed: closed,
      })
      setSearchResults(results.items)
      setHasSearched(true)
    } catch (err: unknown) {
      const message =
        err && typeof err === 'object' && 'response' in err
          ? (err as { response?: { data?: { detail?: string } } }).response?.data?.detail
          : null
      setError(message || 'Failed to search tickets.')
      setSearchResults([])
      setHasSearched(true)
    } finally {
      setIsSearching(false)
    }
  }, [])

  // Trigger debounced search when query or includeClosed changes
  useEffect(() => {
    if (mode !== 'search') return

    if (debounceRef.current) {
      clearTimeout(debounceRef.current)
    }

    if (!searchQuery.trim()) {
      setSearchResults([])
      setHasSearched(false)
      return
    }

    debounceRef.current = setTimeout(() => {
      performSearch(searchQuery, includeClosed)
    }, 300)

    return () => {
      if (debounceRef.current) {
        clearTimeout(debounceRef.current)
      }
    }
  }, [searchQuery, includeClosed, mode, performSearch])

  const handleSelectSearchResult = async (result: PSATicketSearchResult) => {
    setIsLooking(true)
    setError(null)
    try {
      const ticket = await integrationsApi.getTicket(result.id)
      setSelectedTicket(ticket)
      setSelectedTicketId(result.id)
    } catch (err: unknown) {
      const message =
        err && typeof err === 'object' && 'response' in err
          ? (err as { response?: { data?: { detail?: string } } }).response?.data?.detail
          : null
      setError(message || 'Failed to load ticket details.')
    } finally {
      setIsLooking(false)
    }
  }

  const handleManualLookup = async () => {
    const trimmed = manualId.trim()
    if (!trimmed) return

    setIsLooking(true)
    setError(null)
    setSelectedTicket(null)
    setSelectedTicketId(null)

    try {
      const ticket = await integrationsApi.getTicket(trimmed)
      setSelectedTicket(ticket)
      setSelectedTicketId(trimmed)
    } catch (err: unknown) {
      const message =
        err && typeof err === 'object' && 'response' in err
          ? (err as { response?: { data?: { detail?: string } } }).response?.data?.detail
          : null
      setError(message || 'Ticket not found. Please check the ticket number and try again.')
    } finally {
      setIsLooking(false)
    }
  }

  const handleLink = async () => {
    if (!selectedTicket || !selectedTicketId) return

    // Selection-only mode — return ticket data without linking
    if (onSelect) {
      onSelect(selectedTicketId, selectedTicket)
      handleReset()
      onClose()
      return
    }

    // Legacy session linking mode
    if (!sessionId) return

    setIsLinking(true)
    setError(null)
    try {
      await sessionPsaApi.linkTicket(sessionId, selectedTicketId)
      onLinked?.(selectedTicketId, selectedTicket)
      handleReset()
    } catch (err: unknown) {
      const message =
        err && typeof err === 'object' && 'response' in err
          ? (err as { response?: { data?: { detail?: string } } }).response?.data?.detail
          : null
      setError(message || 'Failed to link ticket.')
    } finally {
      setIsLinking(false)
    }
  }

  const handleReset = () => {
    setSearchQuery('')
    setSearchResults([])
    setHasSearched(false)
    setManualId('')
    setSelectedTicket(null)
    setSelectedTicketId(null)
    setError(null)
    setIsLooking(false)
    setIsLinking(false)
    setIsSearching(false)
    setIncludeClosed(false)
  }

  const handleClose = () => {
    handleReset()
    setMode('search')
    onClose()
  }

  const handleClearSelection = () => {
    setSelectedTicket(null)
    setSelectedTicketId(null)
    setError(null)
  }

  const handleManualKeyDown = (e: React.KeyboardEvent) => {
    if (e.key === 'Enter' && manualId.trim() && !isLooking && !selectedTicket) {
      handleManualLookup()
    }
  }

  const switchMode = (newMode: Mode) => {
    setMode(newMode)
    setSelectedTicket(null)
    setSelectedTicketId(null)
    setError(null)
  }

  return (
    <Modal isOpen={open} onClose={handleClose} title={onSelect ? 'Select ConnectWise Ticket' : 'Link ConnectWise Ticket'} size="sm">
      <div className="space-y-4">
        {/* Mode tabs */}
        <div className="flex gap-1 rounded-lg bg-white/[0.03] p-1">
          <button
            type="button"
            onClick={() => switchMode('search')}
            className={cn(
              'flex flex-1 items-center justify-center gap-1.5 rounded-md px-3 py-1.5 text-sm font-medium transition-all',
              mode === 'search'
                ? 'bg-white/[0.08] text-foreground shadow-sm'
                : 'text-muted-foreground hover:text-foreground'
            )}
          >
            <Search className="h-3.5 w-3.5" />
            Search
          </button>
          <button
            type="button"
            onClick={() => switchMode('manual')}
            className={cn(
              'flex flex-1 items-center justify-center gap-1.5 rounded-md px-3 py-1.5 text-sm font-medium transition-all',
              mode === 'manual'
                ? 'bg-white/[0.08] text-foreground shadow-sm'
                : 'text-muted-foreground hover:text-foreground'
            )}
          >
            <Hash className="h-3.5 w-3.5" />
            Ticket #
          </button>
        </div>

        {/* Search mode */}
        {mode === 'search' && !selectedTicket && (
          <div className="space-y-3">
            <div>
              <Input
                type="text"
                placeholder="Search tickets by summary, company, or #..."
                value={searchQuery}
                onChange={(e) => setSearchQuery(e.target.value)}
                disabled={isLooking}
                className="w-full"
                autoFocus
              />
            </div>

            {/* Include closed toggle */}
            <label className="flex cursor-pointer items-center gap-2 text-xs text-muted-foreground">
              <input
                type="checkbox"
                checked={includeClosed}
                onChange={(e) => setIncludeClosed(e.target.checked)}
                className="rounded border-border bg-card accent-primary"
              />
              Include closed tickets
            </label>

            {/* Search results */}
            {isSearching && (
              <div className="flex items-center justify-center py-6">
                <Loader2 className="h-5 w-5 animate-spin text-muted-foreground" />
              </div>
            )}

            {!isSearching && hasSearched && searchResults.length === 0 && (
              <div className="py-6 text-center text-sm text-muted-foreground">
                No tickets found
              </div>
            )}

            {!isSearching && searchResults.length > 0 && (
              <div className="max-h-64 space-y-1 overflow-y-auto">
                {searchResults.map((result) => (
                  <button
                    key={result.id}
                    type="button"
                    onClick={() => handleSelectSearchResult(result)}
                    disabled={isLooking}
                    className={cn(
                      'w-full rounded-lg border border-transparent px-3 py-2.5 text-left transition-all',
                      'hover:border-border hover:bg-input',
                      'disabled:opacity-50',
                      result.closed && 'opacity-60'
                    )}
                  >
                    <p className="truncate text-sm font-medium text-foreground">
                      <span className="text-muted-foreground">#{result.id}</span>
                      {' — '}
                      {result.summary}
                    </p>
                    <div className="mt-0.5 flex flex-wrap items-center gap-x-2 text-xs text-muted-foreground">
                      {result.company_name && <span>{result.company_name}</span>}
                      {result.board_name && (
                        <>
                          <span className="text-text-muted">&bull;</span>
                          <span>{result.board_name}</span>
                        </>
                      )}
                      {result.status_name && (
                        <>
                          <span className="text-text-muted">&bull;</span>
                          <span className={result.closed ? 'text-text-muted' : ''}>
                            {result.status_name}
                          </span>
                        </>
                      )}
                    </div>
                  </button>
                ))}
              </div>
            )}

            {isLooking && (
              <div className="flex items-center justify-center py-3">
                <Loader2 className="h-5 w-5 animate-spin text-muted-foreground" />
                <span className="ml-2 text-sm text-muted-foreground">Loading ticket details...</span>
              </div>
            )}
          </div>
        )}

        {/* Manual mode */}
        {mode === 'manual' && !selectedTicket && (
          <div>
            <label className="mb-1.5 block text-sm font-medium text-foreground">
              Ticket Number
            </label>
            <div className="flex gap-2">
              <Input
                type="text"
                inputMode="numeric"
                placeholder="Enter ticket number..."
                value={manualId}
                onChange={(e) => {
                  setManualId(e.target.value)
                  if (error) setError(null)
                }}
                onKeyDown={handleManualKeyDown}
                disabled={isLooking}
                className="flex-1"
                autoFocus
              />
              <Button
                variant="secondary"
                size="md"
                onClick={handleManualLookup}
                disabled={!manualId.trim() || isLooking}
                loading={isLooking}
              >
                {!isLooking && <Search className="h-4 w-4" />}
                Look Up
              </Button>
            </div>
          </div>
        )}

        {/* Error */}
        {error && (
          <div className="flex items-start gap-2 rounded-lg border border-red-400/20 bg-red-400/10 px-3 py-2.5">
            <AlertCircle className="mt-0.5 h-4 w-4 shrink-0 text-red-400" />
            <p className="text-sm text-red-400">{error}</p>
          </div>
        )}

        {/* Selected ticket confirmation card */}
        {selectedTicket && selectedTicketId && (
          <div className="card-flat space-y-3 rounded-xl border border-border p-4">
            <div className="flex items-start gap-2">
              <CheckCircle2 className="mt-0.5 h-4 w-4 shrink-0 text-emerald-400" />
              <div className="min-w-0">
                <p className="text-sm font-semibold text-foreground">
                  CW #{selectedTicketId} — {selectedTicket.summary}
                </p>
                <div className="mt-1.5 flex flex-wrap items-center gap-x-2 gap-y-1 text-xs text-muted-foreground">
                  {selectedTicket.company_name && (
                    <span>{selectedTicket.company_name}</span>
                  )}
                  {selectedTicket.board_name && (
                    <>
                      <span className="text-text-muted">&bull;</span>
                      <span>{selectedTicket.board_name}</span>
                    </>
                  )}
                  {selectedTicket.status_name && (
                    <>
                      <span className="text-text-muted">&bull;</span>
                      <span>{selectedTicket.status_name}</span>
                    </>
                  )}
                  {selectedTicket.priority_name && (
                    <>
                      <span className="text-text-muted">&bull;</span>
                      <span>{selectedTicket.priority_name}</span>
                    </>
                  )}
                </div>
              </div>
            </div>

            <div className="flex gap-2">
              <Button
                variant="secondary"
                size="md"
                onClick={handleClearSelection}
                disabled={isLinking}
                className="flex-1"
              >
                Back
              </Button>
              <Button
                className="flex-1"
                onClick={handleLink}
                loading={isLinking}
              >
                <Ticket className="h-4 w-4" />
                {onSelect ? 'Select This Ticket' : 'Link This Ticket'}
              </Button>
            </div>
          </div>
        )}

        {/* Skip link */}
        <div className="flex justify-center pt-1">
          <button
            type="button"
            onClick={handleClose}
            className={cn(
              'text-sm text-muted-foreground transition-colors',
              'hover:text-foreground'
            )}
          >
            Skip
          </button>
        </div>
      </div>
    </Modal>
  )
}
