'use client'

import * as React from 'react'
import { Sparkles, AlertCircle, CheckCircle2, MinusCircle } from 'lucide-react'
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogFooter,
  DialogTitle,
  DialogDescription,
} from '../ui/dialog'

/**
 * Minimal subset of the API client surface this component depends on.
 * Lets consumers pass either the full `EnrichmentApi` from `@startsimpli/api`
 * or a custom adapter — keeps this component decoupled from the singleton.
 */
export interface ApolloEnrichmentClient {
  enrichApollo(contactIds: string[]): Promise<ApolloEnrichmentSummary>
}

/** Mirrors `ApolloEnrichmentSummary` from @startsimpli/api. */
export interface ApolloEnrichmentSummary {
  total: number
  enriched: string[]
  skipped: Array<{ contact_id: string; reason: string }>
  errors: Array<{ contact_id: string; error: string }>
  missing: string[]
}

export interface ApolloEnrichButtonProps {
  /** Contact ids to enrich. Disabled when empty. */
  contactIds: string[]
  /** API client with `enrichApollo`. Pass `api.enrichment` from @startsimpli/api. */
  enrichmentApi: ApolloEnrichmentClient
  /** Called once the API call resolves (success or with per-entry errors). */
  onComplete?: (summary: ApolloEnrichmentSummary) => void
  /** Called when the dialog is closed (regardless of completion). */
  onClose?: () => void
  label?: string
  size?: 'sm' | 'md'
  className?: string
  disabled?: boolean
}

type Phase =
  | { kind: 'idle' }
  | { kind: 'running' }
  | { kind: 'done'; summary: ApolloEnrichmentSummary }
  | { kind: 'error'; message: string }

/**
 * Trigger Apollo enrichment for a set of contacts. Opens a dialog showing
 * progress + the per-bucket summary (enriched / skipped / errors / missing).
 *
 * App-agnostic — works for any consumer that can supply an
 * `ApolloEnrichmentClient`.
 */
export function ApolloEnrichButton({
  contactIds,
  enrichmentApi,
  onComplete,
  onClose,
  label = 'Enrich with Apollo',
  size = 'sm',
  className = '',
  disabled = false,
}: ApolloEnrichButtonProps) {
  const [open, setOpen] = React.useState(false)
  const [phase, setPhase] = React.useState<Phase>({ kind: 'idle' })

  const sizeClasses =
    size === 'sm' ? 'px-3 py-1.5 text-xs' : 'px-4 py-2 text-sm'
  const iconClasses = size === 'sm' ? 'w-3 h-3' : 'w-4 h-4'

  const isEmpty = contactIds.length === 0
  const isRunning = phase.kind === 'running'
  const buttonDisabled = disabled || isEmpty || isRunning

  const handleClick = async () => {
    setOpen(true)
    setPhase({ kind: 'running' })
    try {
      const summary = await enrichmentApi.enrichApollo(contactIds)
      setPhase({ kind: 'done', summary })
      onComplete?.(summary)
    } catch (err) {
      setPhase({
        kind: 'error',
        message: err instanceof Error ? err.message : 'Enrichment failed',
      })
    }
  }

  const handleOpenChange = (next: boolean) => {
    setOpen(next)
    if (!next) {
      onClose?.()
      // Reset phase after the dialog finishes closing so the next click
      // starts fresh, but keep the result visible until then.
      setTimeout(() => setPhase({ kind: 'idle' }), 200)
    }
  }

  return (
    <>
      <button
        type="button"
        onClick={handleClick}
        disabled={buttonDisabled}
        aria-label={label}
        className={`flex items-center gap-1.5 font-medium text-primary bg-primary/10 hover:bg-primary/20 rounded-md disabled:opacity-50 disabled:cursor-not-allowed transition-colors ${sizeClasses} ${className}`}
      >
        <Sparkles className={iconClasses} />
        {isRunning ? 'Enriching…' : label}
        {!isEmpty && (
          <span className="ml-1 text-[0.65rem] opacity-75">
            ({contactIds.length})
          </span>
        )}
      </button>

      <Dialog open={open} onOpenChange={handleOpenChange}>
        <DialogContent>
          <DialogHeader>
            <DialogTitle>Apollo enrichment</DialogTitle>
            <DialogDescription>
              {phase.kind === 'running'
                ? `Enriching ${contactIds.length} contact${contactIds.length === 1 ? '' : 's'}…`
                : phase.kind === 'done'
                ? 'Apollo enrichment complete.'
                : phase.kind === 'error'
                ? 'Apollo enrichment failed.'
                : ''}
            </DialogDescription>
          </DialogHeader>

          <div className="space-y-3 py-2">
            {phase.kind === 'running' && (
              <div role="status" aria-live="polite" className="text-sm text-gray-600">
                Reaching Apollo for {contactIds.length} contact
                {contactIds.length === 1 ? '' : 's'}. This may take a few seconds.
              </div>
            )}

            {phase.kind === 'error' && (
              <div role="alert" className="flex items-start gap-2 text-sm text-red-700">
                <AlertCircle className="w-4 h-4 mt-0.5 shrink-0" />
                <span>{phase.message}</span>
              </div>
            )}

            {phase.kind === 'done' && (
              <ApolloEnrichmentSummaryView summary={phase.summary} />
            )}
          </div>

          <DialogFooter>
            <button
              type="button"
              onClick={() => handleOpenChange(false)}
              className="px-4 py-2 text-sm font-medium text-gray-700 bg-gray-100 hover:bg-gray-200 rounded-md"
            >
              {phase.kind === 'running' ? 'Hide' : 'Done'}
            </button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </>
  )
}

function ApolloEnrichmentSummaryView({
  summary,
}: {
  summary: ApolloEnrichmentSummary
}) {
  const enrichedCount = summary.enriched.length
  const skippedCount = summary.skipped.length
  const errorCount = summary.errors.length
  const missingCount = summary.missing.length

  return (
    <div className="space-y-3 text-sm">
      <div className="grid grid-cols-2 gap-2">
        <Stat
          icon={<CheckCircle2 className="w-4 h-4 text-green-600" />}
          label="Enriched"
          value={enrichedCount}
        />
        <Stat
          icon={<MinusCircle className="w-4 h-4 text-gray-500" />}
          label="Skipped"
          value={skippedCount}
        />
        <Stat
          icon={<AlertCircle className="w-4 h-4 text-red-600" />}
          label="Errored"
          value={errorCount}
        />
        <Stat
          icon={<MinusCircle className="w-4 h-4 text-amber-600" />}
          label="Not accessible"
          value={missingCount}
        />
      </div>

      {summary.skipped.length > 0 && (
        <DetailsList
          title="Skipped reasons"
          items={summary.skipped.map((s) => ({
            id: s.contact_id,
            text: s.reason,
          }))}
        />
      )}
      {summary.errors.length > 0 && (
        <DetailsList
          title="Errors"
          items={summary.errors.map((e) => ({
            id: e.contact_id,
            text: e.error,
          }))}
          tone="error"
        />
      )}
    </div>
  )
}

function Stat({
  icon,
  label,
  value,
}: {
  icon: React.ReactNode
  label: string
  value: number
}) {
  return (
    <div className="flex items-center gap-2 px-3 py-2 bg-gray-50 rounded-md">
      {icon}
      <div>
        <div className="text-xs text-gray-500">{label}</div>
        <div className="text-sm font-medium">{value}</div>
      </div>
    </div>
  )
}

function DetailsList({
  title,
  items,
  tone = 'neutral',
}: {
  title: string
  items: Array<{ id: string; text: string }>
  tone?: 'neutral' | 'error'
}) {
  const toneClasses =
    tone === 'error'
      ? 'border-red-200 bg-red-50 text-red-800'
      : 'border-gray-200 bg-gray-50 text-gray-800'
  return (
    <details className={`border rounded-md ${toneClasses}`}>
      <summary className="px-3 py-2 text-xs font-medium cursor-pointer">
        {title} ({items.length})
      </summary>
      <ul className="px-3 py-2 space-y-1 max-h-40 overflow-auto text-xs">
        {items.map((item, i) => (
          <li key={`${item.id}-${i}`} className="font-mono">
            <span className="opacity-50">{item.id.slice(0, 8)}…</span>{' '}
            <span className="font-sans">{item.text}</span>
          </li>
        ))}
      </ul>
    </details>
  )
}
