import { useState, useEffect } from 'react'
import { Loader2, Copy, AlertTriangle, AlertCircle, RefreshCw } from 'lucide-react'
import { Modal } from '@/components/common/Modal'
import { Textarea } from '@/components/ui/Textarea'
import { cn } from '@/lib/utils'
import { toast } from '@/lib/toast'
import { sessionPsaApi } from '@/api/integrations'
import type { PsaPreviewResponse } from '@/types/integrations'

interface Props {
  open: boolean
  onClose: () => void
  sessionId: string
  onPosted?: () => void
}

type NoteType = 'internal_analysis' | 'resolution' | 'description'

const NOTE_TYPE_OPTIONS: { value: NoteType; label: string; description: string; warning?: string }[] = [
  { value: 'internal_analysis', label: 'Internal Analysis', description: 'Internal only, no notifications' },
  { value: 'resolution', label: 'Resolution', description: 'Internal only, triggers notifications' },
  { value: 'description', label: 'Description', description: 'Visible to the customer', warning: 'This note will be visible to the customer' },
]

const CHAR_WARNING_THRESHOLD = 15000

export function UpdateTicketModal({ open, onClose, sessionId, onPosted }: Props) {
  const [preview, setPreview] = useState<PsaPreviewResponse | null>(null)
  const [isLoading, setIsLoading] = useState(false)
  const [loadError, setLoadError] = useState<string | null>(null)

  const [content, setContent] = useState('')
  const [noteType, setNoteType] = useState<NoteType>('internal_analysis')
  const [selectedStatusId, setSelectedStatusId] = useState<number | null>(null)

  const [isPosting, setIsPosting] = useState(false)
  const [postError, setPostError] = useState<string | null>(null)

  useEffect(() => {
    if (open) {
      loadPreview()
    } else {
      // Reset state when closed
      setPreview(null)
      setContent('')
      setNoteType('internal_analysis')
      setSelectedStatusId(null)
      setPostError(null)
      setLoadError(null)
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [open, sessionId])

  const loadPreview = async () => {
    setIsLoading(true)
    setLoadError(null)
    try {
      const data = await sessionPsaApi.getPostPreview(sessionId)
      setPreview(data)
      setContent(data.content)
      // Find current status ID from available_statuses matching ticket status_name
      const currentStatus = data.available_statuses.find(
        (s) => s.name === data.ticket.status_name
      )
      setSelectedStatusId(currentStatus?.id ?? null)
    } catch (err) {
      const axiosErr = err as { response?: { data?: { detail?: string } } }
      setLoadError(axiosErr.response?.data?.detail || 'Failed to load preview')
      console.error(err)
    } finally {
      setIsLoading(false)
    }
  }

  const handleCopyContent = async () => {
    try {
      await navigator.clipboard.writeText(content)
      toast.success('Content copied to clipboard')
    } catch {
      toast.error('Failed to copy content')
    }
  }

  const handlePost = async () => {
    setIsPosting(true)
    setPostError(null)
    try {
      // Determine if status should be updated
      const currentStatus = preview?.available_statuses.find(
        (s) => s.name === preview?.ticket.status_name
      )
      const statusChanged = selectedStatusId !== null && selectedStatusId !== currentStatus?.id

      await sessionPsaApi.postToTicket(sessionId, {
        note_type: noteType,
        content,
        ...(statusChanged ? { update_status_id: selectedStatusId } : {}),
      })

      toast.success('Note posted to ticket successfully')
      onPosted?.()
      onClose()
    } catch (err) {
      const axiosErr = err as { response?: { data?: { detail?: string } } }
      setPostError(axiosErr.response?.data?.detail || 'Failed to post to ticket')
      console.error(err)
    } finally {
      setIsPosting(false)
    }
  }

  const currentStatusId = preview?.available_statuses.find(
    (s) => s.name === preview?.ticket.status_name
  )?.id

  const footer = (
    <div className="space-y-3">
      {postError && (
        <div className="flex items-center justify-between gap-2 rounded-lg border border-red-400/20 bg-red-400/10 px-3 py-2 text-sm text-red-400">
          <div className="flex items-center gap-2">
            <AlertCircle className="h-4 w-4 shrink-0" />
            <span>{postError}</span>
          </div>
          <button
            onClick={handlePost}
            className="inline-flex items-center gap-1.5 shrink-0 text-xs font-medium hover:text-red-300 transition-colors"
          >
            <RefreshCw className="h-3 w-3" />
            Retry
          </button>
        </div>
      )}
      <div className="flex items-center justify-end gap-3">
        <button
          type="button"
          onClick={onClose}
          className="text-sm text-muted-foreground hover:text-foreground transition-colors"
        >
          Cancel
        </button>
        <button
          type="button"
          onClick={handlePost}
          disabled={isPosting || !content.trim()}
          className={cn(
            'inline-flex items-center gap-2 rounded-lg px-5 py-2.5 text-sm font-semibold',
            'bg-primary text-white',
            'hover:brightness-110 active:scale-[0.98] transition-all',
            'disabled:opacity-50 disabled:cursor-not-allowed'
          )}
        >
          {isPosting && <Loader2 className="h-4 w-4 animate-spin" />}
          Update Ticket
        </button>
      </div>
    </div>
  )

  return (
    <Modal isOpen={open} onClose={onClose} title="Update Ticket" size="xl" footer={footer}>
      {isLoading && (
        <div className="flex items-center justify-center py-12">
          <Loader2 className="h-8 w-8 animate-spin text-muted-foreground" />
        </div>
      )}

      {loadError && (
        <div className="flex flex-col items-center gap-3 py-8">
          <div className="flex items-center gap-2 text-red-400">
            <AlertCircle className="h-5 w-5" />
            <span className="text-sm">{loadError}</span>
          </div>
          <button
            onClick={loadPreview}
            className="text-sm text-muted-foreground hover:text-foreground transition-colors"
          >
            Try again
          </button>
        </div>
      )}

      {preview && !isLoading && (
        <div className="grid gap-6 lg:grid-cols-2">
          {/* Left panel - Content editor */}
          <div className="space-y-3">
            <div className="flex items-center justify-between">
              <p className="font-sans text-xs text-[0.625rem] uppercase tracking-[0.1em] text-muted-foreground">
                Note Content
              </p>
              <button
                type="button"
                onClick={handleCopyContent}
                className="inline-flex items-center gap-1 rounded px-1.5 py-0.5 text-xs text-muted-foreground hover:text-foreground transition-colors"
                title="Copy content"
              >
                <Copy className="h-3 w-3" />
                Copy
              </button>
            </div>

            <Textarea
              value={content}
              onChange={(e) => setContent(e.target.value)}
              rows={18}
              className="min-h-[300px] resize-y font-mono text-xs"
            />

            <div className="flex items-center justify-between text-xs">
              {content.length >= CHAR_WARNING_THRESHOLD ? (
                <span className="flex items-center gap-1 text-amber-400">
                  <AlertTriangle className="h-3 w-3" />
                  Content may be truncated by ConnectWise
                </span>
              ) : (
                <span />
              )}
              <span className="text-muted-foreground">
                {content.length.toLocaleString()} characters
              </span>
            </div>
          </div>

          {/* Right panel - Controls */}
          <div className="space-y-6">
            {/* Ticket info summary */}
            <div className="card-flat rounded-lg border border-border p-3">
              <p className="text-sm font-medium text-foreground">
                CW #{preview.ticket.id}
                {preview.ticket.summary && (
                  <span className="text-muted-foreground"> — {preview.ticket.summary}</span>
                )}
              </p>
              {(preview.ticket.company_name || preview.ticket.board_name) && (
                <p className="mt-1 text-xs text-muted-foreground">
                  {[preview.ticket.company_name, preview.ticket.board_name].filter(Boolean).join(' / ')}
                </p>
              )}
            </div>

            {/* Note Type */}
            <div>
              <p className="font-sans text-xs text-[0.625rem] uppercase tracking-[0.1em] text-muted-foreground mb-3">
                Note Type
              </p>
              <div className="space-y-2">
                {NOTE_TYPE_OPTIONS.map((opt) => (
                  <label
                    key={opt.value}
                    className={cn(
                      'flex cursor-pointer items-start gap-3 rounded-lg border px-3 py-2.5 transition-colors',
                      noteType === opt.value
                        ? 'border-primary/30 bg-primary/5'
                        : 'border-border hover:border-[rgba(255,255,255,0.12)]'
                    )}
                  >
                    <input
                      type="radio"
                      name="note_type"
                      value={opt.value}
                      checked={noteType === opt.value}
                      onChange={() => setNoteType(opt.value)}
                      className="mt-0.5 accent-blue-400"
                    />
                    <div className="min-w-0">
                      <span className="text-sm font-medium text-foreground">{opt.label}</span>
                      <p className="text-xs text-muted-foreground">{opt.description}</p>
                      {opt.warning && noteType === opt.value && (
                        <p className="mt-1 flex items-center gap-1 text-xs text-amber-400">
                          <AlertTriangle className="h-3 w-3 shrink-0" />
                          {opt.warning}
                        </p>
                      )}
                    </div>
                  </label>
                ))}
              </div>
            </div>

            {/* Ticket Status */}
            <div>
              <p className="font-sans text-xs text-[0.625rem] uppercase tracking-[0.1em] text-muted-foreground mb-2">
                Ticket Status
              </p>
              <select
                value={selectedStatusId ?? ''}
                onChange={(e) => setSelectedStatusId(e.target.value ? Number(e.target.value) : null)}
                className={cn(
                  'w-full rounded-md border border-border bg-card px-3 py-2 text-sm text-foreground',
                  'focus:border-primary/30 focus:outline-hidden focus:ring-1 focus:ring-primary/20'
                )}
              >
                {preview.available_statuses.map((status) => (
                  <option key={status.id} value={status.id}>
                    {status.name}
                    {status.id === currentStatusId ? ' (current)' : ''}
                    {status.is_closed ? ' [closed]' : ''}
                  </option>
                ))}
              </select>
            </div>

            {/* Previous posts */}
            {preview.previous_posts > 0 && (
              <p className="text-xs text-muted-foreground">
                This session has been posted {preview.previous_posts} time{preview.previous_posts > 1 ? 's' : ''} before.
              </p>
            )}
          </div>
        </div>
      )}
    </Modal>
  )
}
