import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import type { CSSProperties } from 'react'
import { ArrowRight, Ban, Check, Copy, LogOut, Mail, MessageSquare, Phone, Plus, Search, Settings, Stethoscope, X, Zap } from 'lucide-react'
import { AgentAvatarBadge } from '../components/common/AgentAvatarBadge'
import { Modal } from '../components/common/Modal'
import { normalizeHexColor } from '../util/color'
import { track } from '../util/analytics'
import { leaveCollaboration } from '../api/agents'
import { useModal } from '../hooks/useModal'
import { buildAgentSearchBlob, styleStringToObject } from '../util/agentCards'
import type { AccountPauseInfo } from '../types/agentAddons'

type AgentSummary = {
  id: string
  name: string
  signupPreviewState: string | null
  avatarUrl: string | null
  listingDescription: string
  listingDescriptionSource: string | null
  miniDescription: string
  miniDescriptionSource: string | null
  displayTags: string[]
  isActive: boolean
  pendingTransfer: boolean
  primaryEmail: string | null
  primarySms: string | null
  detailUrl: string
  chatUrl: string
  auditUrl: string | null
  cardGradientStyle: string
  iconBackgroundHex: string
  iconBorderHex: string
  displayColorHex: string | null
  headerTextClass: string
  headerSubtextClass: string
  headerStatusClass: string
  headerBadgeClass: string
  headerIconClass: string
  headerLinkHoverClass: string
  dailyCreditRemaining: number | null
  dailyCreditLow: boolean
  last24hCreditBurn: number | null
  isShared: boolean
}

type AgentListPayload = {
  agents: AgentSummary[]
  sharedAgents: AgentSummary[]
  hasAgents: boolean
  hasSharedAgents: boolean
  spawnAgentUrl: string
  upgradeUrl: string | null
  canSpawnAgents: boolean
  showUpgradeCta: boolean
  createFirstAgentEvent: string | null
  agentsAvailable: number
  agentsUnlimited: boolean
  isStaff: boolean
  emailVerified: boolean
  accountPause?: AccountPauseInfo | null
}

export type PersistentAgentsScreenProps = {
  initialData: AgentListPayload
}

type NormalizedAgent = AgentSummary & {
  searchBlob: string
  gradientStyle: CSSProperties
}

function normalizeAgents(agents: AgentSummary[]): NormalizedAgent[] {
  return agents.map((agent) => ({
    ...agent,
    displayTags: agent.displayTags ?? [],
    searchBlob: buildSearchBlob(agent),
    gradientStyle: styleStringToObject(agent.cardGradientStyle),
  }))
}

function formatCreditBurn(value: number | null): string {
  if (value == null || value <= 0 || Number.isNaN(value)) {
    return '0 credits/day'
  }
  const fractionDigits = value < 1 ? 2 : value < 10 ? 1 : 0
  return `${value.toFixed(fractionDigits)} credits/day`
}

function formatAccountPauseResumeLabel(resumeAt?: string | null): string | null {
  if (!resumeAt) return null
  const resumeDate = new Date(resumeAt)
  if (Number.isNaN(resumeDate.getTime())) return null
  return new Intl.DateTimeFormat(undefined, {
    month: 'short',
    day: 'numeric',
    year: 'numeric',
    hour: 'numeric',
    minute: '2-digit',
  }).format(resumeDate)
}

export function PersistentAgentsScreen({ initialData }: PersistentAgentsScreenProps) {
  const [query, setQuery] = useState('')
  const [showVerificationDialog, setShowVerificationDialog] = useState(false)
  const [sharedAgents, setSharedAgents] = useState<NormalizedAgent[]>(() => normalizeAgents(initialData.sharedAgents))
  const [modal, showModal] = useModal()
  const accountPause = initialData.accountPause ?? null
  const accountPaused = Boolean(accountPause?.paused)

  const normalizedAgents = useMemo<NormalizedAgent[]>(() => {
    return normalizeAgents(initialData.agents)
  }, [initialData.agents])

  const hasAnyAgents = normalizedAgents.length > 0 || sharedAgents.length > 0
  const filteredAgents = useMemo(() => {
    if (!query.trim()) {
      return normalizedAgents
    }
    const needle = query.trim().toLowerCase()
    return normalizedAgents.filter((agent) => agent.searchBlob.includes(needle))
  }, [normalizedAgents, query])
  const filteredSharedAgents = useMemo(() => {
    if (!query.trim()) {
      return sharedAgents
    }
    const needle = query.trim().toLowerCase()
    return sharedAgents.filter((agent) => agent.searchBlob.includes(needle))
  }, [sharedAgents, query])

  const showEmptyState = !hasAnyAgents
  const showEmptySearch = hasAnyAgents && filteredAgents.length === 0 && filteredSharedAgents.length === 0

  const handleContactClick = useCallback(
    (e: React.MouseEvent<HTMLAnchorElement>) => {
      if (!initialData.emailVerified) {
        e.preventDefault()
        setShowVerificationDialog(true)
      }
    },
    [initialData.emailVerified],
  )

  const handleLeaveCollaboration = useCallback(
    (agent: NormalizedAgent) => {
      showModal((onClose) => (
        <LeaveCollaborationDialog
          agentName={agent.name}
          onClose={onClose}
          onConfirm={async () => {
            await leaveCollaboration(agent.id)
            setSharedAgents((prev) => prev.filter((item) => item.id !== agent.id))
          }}
        />
      ))
    },
    [setSharedAgents, showModal],
  )

  return (
    <div className="space-y-6 pb-6">
      {showVerificationDialog && (
        <EmailVerificationDialog onClose={() => setShowVerificationDialog(false)} />
      )}
      {modal}
      {accountPaused ? <AccountPausedBanner accountPause={accountPause} /> : null}
      {showEmptyState ? (
        <AgentEmptyState
          spawnUrl={initialData.spawnAgentUrl}
          analyticsEvent={initialData.createFirstAgentEvent}
          accountPaused={accountPaused}
        />
      ) : (
        <>
          <AgentListHeader
            query={query}
            onSearchChange={setQuery}
            canSpawnAgents={initialData.canSpawnAgents && !accountPaused}
            spawnUrl={initialData.spawnAgentUrl}
            showUpgradeCta={initialData.showUpgradeCta && !accountPaused}
            upgradeUrl={initialData.upgradeUrl}
          />

          {filteredAgents.length > 0 && (
            <div className="space-y-4">
              <div className="flex items-center justify-between">
                <h2 className="text-lg font-semibold text-gray-800">Your agents</h2>
                <span className="text-xs text-gray-500">{filteredAgents.length} active</span>
              </div>
              <div className="grid grid-cols-1 gap-6 lg:grid-cols-2 2xl:grid-cols-3">
                {filteredAgents.map((agent) => (
                  <AgentCard
                    key={agent.id}
                    agent={agent}
                    onContactClick={handleContactClick}
                  />
                ))}
              </div>
            </div>
          )}

          {filteredSharedAgents.length > 0 && (
            <div className="space-y-4">
              <div className="flex items-center justify-between">
                <h2 className="text-lg font-semibold text-gray-800">Shared with you</h2>
                <span className="text-xs text-gray-500">{filteredSharedAgents.length} shared</span>
              </div>
              <div className="grid grid-cols-1 gap-6 lg:grid-cols-2 2xl:grid-cols-3">
                {filteredSharedAgents.map((agent) => (
                  <AgentCard
                    key={agent.id}
                    agent={agent}
                    onContactClick={handleContactClick}
                    onLeaveCollaboration={handleLeaveCollaboration}
                  />
                ))}
              </div>
            </div>
          )}

          {showEmptySearch && (
            <div
              id="agent-search-empty"
              className="text-center py-12 bg-white rounded-xl shadow-inner border border-dashed border-gray-200"
            >
              <p className="text-sm font-semibold text-gray-700">No agents match your search yet.</p>
              <p className="text-sm text-gray-500 mt-1">Try another keyword or clear the search box.</p>
            </div>
          )}
        </>
      )}
    </div>
  )
}

function AccountPausedBanner({ accountPause }: { accountPause: AccountPauseInfo | null }) {
  const resumeLabel = formatAccountPauseResumeLabel(accountPause?.resumeAt)
  const message = resumeLabel
    ? `Your account is paused until ${resumeLabel}. New agents and messages are disabled until billing resumes.`
    : 'Your account is paused. New agents and messages are disabled until billing resumes.'

  return (
    <div className="rounded-xl border border-amber-200 bg-amber-50 px-4 py-3 text-amber-950">
      <div className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
        <div className="flex min-w-0 items-start gap-3">
          <span className="mt-0.5 inline-flex size-8 shrink-0 items-center justify-center rounded-lg bg-amber-100 text-amber-700">
            <Ban className="size-4" aria-hidden="true" />
          </span>
          <div className="min-w-0">
            <p className="text-sm font-semibold">Account paused</p>
            <p className="mt-1 text-sm text-amber-900">{message}</p>
          </div>
        </div>
        {accountPause?.manageBillingUrl ? (
          <a
            href={accountPause.manageBillingUrl}
            className="inline-flex shrink-0 items-center justify-center rounded-lg bg-amber-700 px-4 py-2 text-sm font-semibold text-white transition hover:bg-amber-800 focus:outline-none focus:ring-2 focus:ring-amber-500 focus:ring-offset-2"
          >
            Open billing
          </a>
        ) : null}
      </div>
    </div>
  )
}

type AgentListHeaderProps = {
  query: string
  onSearchChange: (value: string) => void
  canSpawnAgents: boolean
  spawnUrl: string
  showUpgradeCta: boolean
  upgradeUrl: string | null
}

function AgentListHeader({ query, onSearchChange, canSpawnAgents, spawnUrl, showUpgradeCta, upgradeUrl }: AgentListHeaderProps) {
  return (
    <div className="bg-white/80 backdrop-blur-sm shadow-xl rounded-xl overflow-hidden">
      <div className="px-6 py-4 border-b border-gray-200/70">
        <div className="flex flex-col gap-4 lg:flex-row lg:items-center lg:justify-between">
          <div>
            <h1 className="text-2xl font-semibold text-gray-800">Agents</h1>
            <p className="text-sm text-gray-500 mt-1">Manage your always-on AI agents.</p>
          </div>
          <div className="flex w-full flex-col gap-3 sm:flex-row sm:items-center lg:w-auto">
            <div className="relative flex-1 sm:w-64 sm:flex-none">
              <Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-gray-400" aria-hidden="true" />
              <input
                id="agent-search-input"
                type="search"
                placeholder="Search Agents..."
                className="w-full pl-9 pr-3 py-2.5 rounded-lg border border-gray-200 bg-white text-sm text-gray-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent shadow-sm transition"
                autoComplete="off"
                value={query}
                onChange={(event) => onSearchChange(event.currentTarget.value)}
              />
            </div>

            {canSpawnAgents && (
              <a
                href={spawnUrl}
                className="group relative inline-flex w-full items-center justify-center rounded-lg bg-gradient-to-r from-blue-600 to-indigo-600 px-6 py-3 font-semibold text-white shadow-lg transition-all duration-300 hover:from-blue-700 hover:to-indigo-700 hover:shadow-xl focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 sm:w-auto"
              >
                <span className="mr-2 h-2.5 w-2.5 animate-pulse rounded-full bg-emerald-400" />
                <span className="relative">Spawn Agent</span>
              </a>
            )}

            {!canSpawnAgents && showUpgradeCta && upgradeUrl && (
              <div className="inline-flex w-full items-center rounded-lg border border-gray-200 bg-gradient-to-r from-gray-50 to-gray-100 p-4 shadow-sm sm:w-auto">
                <div className="flex items-center space-x-3">
                  <div className="flex-shrink-0">
                    <div className="flex h-10 w-10 items-center justify-center rounded-full bg-gray-200">
                      <Ban className="h-5 w-5 text-gray-400" aria-hidden="true" />
                    </div>
                  </div>
                  <div className="flex-1">
                    <p className="text-sm font-medium text-gray-700">No agents available</p>
                    <p className="mt-1 text-xs text-gray-500">Upgrade your plan to create more agents</p>
                  </div>
                  <div className="flex-shrink-0">
                    <a
                      href={upgradeUrl}
                      className="inline-flex items-center rounded-md bg-blue-600 px-3 py-1.5 text-xs font-medium text-white transition-colors duration-200 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2"
                    >
                      <Zap className="mr-1 h-3 w-3" aria-hidden="true" />
                      Upgrade
                    </a>
                  </div>
                </div>
              </div>
            )}
          </div>
        </div>
      </div>
    </div>
  )
}

type AgentCardProps = {
  agent: NormalizedAgent
  onContactClick?: (e: React.MouseEvent<HTMLAnchorElement>) => void
  onLeaveCollaboration?: (agent: NormalizedAgent) => void
}

function AgentCard({ agent, onContactClick, onLeaveCollaboration }: AgentCardProps) {
  const creditsRemaining = agent.dailyCreditRemaining !== null ? agent.dailyCreditRemaining.toFixed(2) : null
  const creditsBurnLast24h = formatCreditBurn(agent.last24hCreditBurn)
  const isSignupPreviewAgent = !agent.isShared && Boolean(agent.signupPreviewState) && agent.signupPreviewState !== 'none'
  const smsValue = agent.primarySms
  const emailValue = agent.primaryEmail
  const chatValue = agent.chatUrl
  const nameHref = isSignupPreviewAgent ? chatValue : agent.detailUrl
  const nameUsesImmersiveLink = Boolean(chatValue) && nameHref === chatValue
  const hasTags = agent.displayTags.length > 0
  const showSmsAction = Boolean(smsValue) && !isSignupPreviewAgent
  const showEmailAction = Boolean(emailValue) && !isSignupPreviewAgent
  const showChatAction = Boolean(chatValue)
  const hasChannels = showSmsAction || showEmailAction || showChatAction
  const canLeave = agent.isShared && Boolean(onLeaveCollaboration)
  const [copiedField, setCopiedField] = useState<null | 'sms' | 'email'>(null)
  const copyResetTimeout = useRef<number | null>(null)

  const handleCopy = async (value: string, field: 'sms' | 'email') => {
    if (typeof navigator === 'undefined' || !navigator.clipboard) {
      return
    }
    try {
      await navigator.clipboard.writeText(value)
      setCopiedField(field)
      if (copyResetTimeout.current !== null) {
        window.clearTimeout(copyResetTimeout.current)
      }
      copyResetTimeout.current = window.setTimeout(() => {
        setCopiedField(null)
      }, 1600)
    } catch (err) {
      console.error('Copy failed', err)
    }
  }

  useEffect(() => {
    return () => {
      if (copyResetTimeout.current !== null) {
        window.clearTimeout(copyResetTimeout.current)
      }
    }
  }, [])
  const accentColor = normalizeHexColor(agent.displayColorHex || agent.iconBorderHex || agent.iconBackgroundHex)
  const creditWarningSuffix = agent.isShared
    ? 'Ask the owner to adjust the daily limit if you need them to keep working today.'
    : 'Increase the daily limit on the agent detail page if you want them to keep working today.'

  return (
    <div className="gobii-card-hoverable group relative flex h-full flex-col">
      <div className="relative flex h-44 flex-col items-center justify-center overflow-hidden" style={agent.gradientStyle}>
        <div
          className="absolute inset-0 opacity-20"
          style={{ background: 'radial-gradient(circle at 20% 20%, rgba(255, 255, 255, 0.35), transparent 55%)' }}
        />
        <div
          className="absolute inset-0 opacity-10"
          style={{ background: 'radial-gradient(circle at 80% 0%, rgba(255, 255, 255, 0.25), transparent 60%)' }}
        />

        <AgentAvatarBadge
          name={agent.name}
          avatarUrl={agent.avatarUrl}
          className="relative z-10 mb-3 flex size-14 items-center justify-center overflow-hidden rounded-full border backdrop-blur-sm"
          imageClassName="h-full w-full object-cover"
          textClassName={`flex h-full w-full items-center justify-center text-xl font-semibold uppercase ${agent.headerIconClass} text-white`}
          style={{ backgroundColor: agent.iconBackgroundHex, borderColor: agent.iconBorderHex }}
          fallbackStyle={{ background: `linear-gradient(135deg, ${accentColor}, #0f172a)` }}
        />

        <h3 className={`relative z-10 px-4 text-center text-lg font-semibold ${agent.headerTextClass}`}>
          <a
            href={nameHref}
            data-immersive-link={nameUsesImmersiveLink ? true : undefined}
            className="transition duration-200 hover:drop-shadow-[0_0_10px_rgba(255,255,255,0.45)] focus-visible:underline focus-visible:outline-none"
          >
            {agent.name}
          </a>
        </h3>

        <div className={`relative z-10 mt-2 flex flex-wrap items-center gap-2 ${agent.headerStatusClass}`}>
          <span className={`size-2 rounded-full ${agent.isActive ? 'bg-green-300' : 'bg-gray-300'}`} />
          <span className="text-xs font-medium uppercase tracking-wide">{agent.isActive ? 'Active' : 'Paused'}</span>
          <span className="inline-flex items-center rounded-full border border-white/60 bg-white/90 px-3 py-1 text-xs font-semibold text-slate-700 shadow-sm backdrop-blur">
            {creditsBurnLast24h}
          </span>
        </div>

        {agent.pendingTransfer && (
          <div className={`relative z-10 mt-2 inline-flex items-center gap-2 rounded-full px-3 py-1 text-xs font-semibold ${agent.headerBadgeClass}`}>
            <span className="sr-only">Transfer pending</span>
            <ArrowRight className="h-3.5 w-3.5" aria-hidden="true" />
            <span>Transfer Pending</span>
          </div>
        )}

        {canLeave && (
          <button
            type="button"
            onClick={() => onLeaveCollaboration?.(agent)}
            className="absolute left-3 top-3 inline-flex items-center gap-1.5 rounded-full border border-rose-200 bg-rose-50 px-3 py-1.5 text-xs font-semibold text-rose-700 shadow-sm backdrop-blur transition hover:bg-rose-100"
          >
            <LogOut className="h-4 w-4" aria-hidden="true" />
            Leave
          </button>
        )}

        {!agent.isShared && !isSignupPreviewAgent && (
          <a
            href={agent.detailUrl}
            className="absolute left-3 top-3 inline-flex items-center gap-1.5 rounded-full border border-white/70 bg-white/90 px-3 py-1.5 text-xs font-semibold text-slate-700 shadow-sm backdrop-blur transition hover:bg-white"
          >
            <Settings className="h-4 w-4" aria-hidden="true" />
            Configure
          </a>
        )}

        {agent.auditUrl && !isSignupPreviewAgent ? (
          <a
            href={agent.auditUrl}
            className="absolute right-3 top-3 inline-flex items-center gap-1.5 rounded-full border border-amber-200/80 bg-amber-50/90 px-3 py-1.5 text-xs font-semibold text-amber-800 shadow-sm backdrop-blur transition hover:bg-amber-100 hover:border-amber-200"
            title="View agent audit"
          >
            <Stethoscope className="h-4 w-4" aria-hidden="true" />
            Audit
          </a>
        ) : null}
      </div>

      <div className="flex flex-1 flex-col p-2.5 md:p-3">
        {agent.dailyCreditLow && (
          <div className="mb-4 rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-xs font-semibold text-amber-800">
            {agent.name} is almost out of daily task credits
            {creditsRemaining !== null && ` (${creditsRemaining} left)`}. {creditWarningSuffix}
          </div>
        )}

        <div className={hasTags ? '' : 'flex-1'}>
          {agent.miniDescription && agent.miniDescriptionSource !== 'placeholder' ? (
            <p className="text-sm font-semibold text-gray-600">{agent.miniDescription}</p>
          ) : agent.listingDescriptionSource === 'placeholder' ? (
            <p className="text-sm italic text-gray-400">{agent.listingDescription}</p>
          ) : (
            <p
              className="text-sm text-gray-600"
              style={{ display: '-webkit-box', WebkitLineClamp: 3, WebkitBoxOrient: 'vertical', overflow: 'hidden' }}
            >
              {agent.listingDescription}
            </p>
          )}
        </div>

        {hasTags && (
          <div className="mt-4 flex flex-1 flex-wrap content-start gap-2">
            {agent.displayTags.map((tag) => (
              <span
                key={tag}
                className="inline-flex items-center rounded-full border border-indigo-100 bg-indigo-50 px-2.5 py-1 text-xs font-medium text-indigo-700"
              >
                {tag}
              </span>
            ))}
          </div>
        )}

        {hasChannels && (
          <div className="mt-4 pt-4">
            <div className="flex flex-wrap items-stretch gap-2">
              {showSmsAction && smsValue && (
                <div className="inline-flex min-w-[7.5rem] flex-1 items-stretch overflow-hidden rounded-lg border border-emerald-600/80">
                  <a
                    href={`sms:${smsValue}`}
                    onClick={onContactClick}
                    className="inline-flex flex-1 items-center justify-center gap-x-2 bg-emerald-600 px-3 py-2 text-sm font-semibold text-white transition hover:bg-emerald-700"
                  >
                    <Phone className="h-4 w-4" aria-hidden="true" />
                    SMS
                  </a>
                  <button
                    type="button"
                    onClick={() => handleCopy(smsValue, 'sms')}
                    data-copied={copiedField === 'sms'}
                    title={copiedField === 'sms' ? 'Copied!' : 'Copy SMS number'}
                    aria-label="Copy SMS number"
                    className="group relative inline-flex w-8 flex-none shrink-0 items-center justify-center border-l border-emerald-500/70 bg-emerald-600 px-2.5 py-2 text-white/80 transition hover:bg-emerald-700 hover:text-white data-[copied=true]:bg-emerald-700 data-[copied=true]:text-white"
                  >
                    {copiedField === 'sms' ? <Check className="h-4 w-4" aria-hidden="true" /> : <Copy className="h-4 w-4" aria-hidden="true" />}
                    <span className="pointer-events-none absolute -top-7 left-1/2 -translate-x-1/2 rounded-md bg-slate-900 px-2 py-1 text-[10px] font-semibold uppercase tracking-wide text-white opacity-0 transition group-data-[copied=true]:opacity-100">
                      Copied
                    </span>
                  </button>
                </div>
              )}
              {showEmailAction && emailValue && (
                <div className="inline-flex min-w-[7.5rem] flex-1 items-stretch overflow-hidden rounded-lg border border-sky-600/80">
                  <a
                    href={`mailto:${emailValue}`}
                    onClick={onContactClick}
                    className="inline-flex flex-1 items-center justify-center gap-x-2 bg-sky-600 px-3 py-2 text-sm font-semibold text-white transition hover:bg-sky-700"
                  >
                    <Mail className="h-4 w-4" aria-hidden="true" />
                    Email
                  </a>
                  <button
                    type="button"
                    onClick={() => handleCopy(emailValue, 'email')}
                    data-copied={copiedField === 'email'}
                    title={copiedField === 'email' ? 'Copied!' : 'Copy email address'}
                    aria-label="Copy email address"
                    className="group relative inline-flex w-8 flex-none shrink-0 items-center justify-center border-l border-sky-500/70 bg-sky-600 px-2.5 py-2 text-white/80 transition hover:bg-sky-700 hover:text-white data-[copied=true]:bg-sky-700 data-[copied=true]:text-white"
                  >
                    {copiedField === 'email' ? <Check className="h-4 w-4" aria-hidden="true" /> : <Copy className="h-4 w-4" aria-hidden="true" />}
                    <span className="pointer-events-none absolute -top-7 left-1/2 -translate-x-1/2 rounded-md bg-slate-900 px-2 py-1 text-[10px] font-semibold uppercase tracking-wide text-white opacity-0 transition group-data-[copied=true]:opacity-100">
                      Copied
                    </span>
                  </button>
                </div>
              )}
              {showChatAction && chatValue && (
                <a
                  href={chatValue}
                  data-immersive-link
                  className="inline-flex min-w-[6.5rem] flex-1 items-center justify-center gap-x-2 rounded-lg bg-indigo-600 px-3 py-2 text-sm font-semibold text-white transition hover:bg-indigo-700"
                >
                  <MessageSquare className="h-4 w-4" aria-hidden="true" />
                  Chat
                </a>
              )}
            </div>
          </div>
        )}
      </div>
    </div>
  )
}

type AgentEmptyStateProps = {
  spawnUrl: string
  analyticsEvent: string | null
  accountPaused: boolean
}

function AgentEmptyState({ spawnUrl, analyticsEvent, accountPaused }: AgentEmptyStateProps) {
  const handleClick = () => {
    if (analyticsEvent) {
      track(analyticsEvent)
    }
  }

  return (
    <div className="bg-white/80 backdrop-blur-sm shadow-xl rounded-xl overflow-hidden">
      <div className="mx-auto flex min-h-96 w-full max-w-md flex-col items-center justify-center px-6 py-16">
        <div className="mb-8 flex size-20 items-center justify-center rounded-full bg-gradient-to-br from-blue-600 to-indigo-600 text-white shadow-xl">
          <Zap className="size-8" aria-hidden="true" />
        </div>
        <h2 className="mb-3 text-center text-xl font-semibold text-gray-800">No always-on agents yet</h2>
        <p className="mb-6 text-center text-sm text-gray-600 leading-relaxed">
          Create your first AI agent that works 24/7. Agents can automate tasks, monitor changes, send notifications, and much more while you focus on what matters.
        </p>
        <div className="flex flex-col gap-3">
          {accountPaused ? (
            <button
              type="button"
              disabled
              className="inline-flex cursor-not-allowed items-center justify-center gap-x-2 rounded-lg bg-amber-100 px-6 py-3 font-semibold text-amber-800"
            >
              <Ban className="size-5 shrink-0" aria-hidden="true" />
              Account paused
            </button>
          ) : (
            <a
              href={spawnUrl}
              onClick={handleClick}
              className="group inline-flex items-center justify-center gap-x-2 rounded-lg bg-gradient-to-r from-blue-600 to-indigo-600 px-6 py-3 font-semibold text-white shadow-lg transition-all duration-300 hover:from-blue-700 hover:to-indigo-700 hover:shadow-xl focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2"
            >
              <Plus className="size-5 shrink-0 transition-transform duration-300 group-hover:rotate-12" aria-hidden="true" />
              Create Your First Agent
            </a>
          )}
        </div>
      </div>
    </div>
  )
}

type EmailVerificationDialogProps = {
  onClose: () => void
}

function EmailVerificationDialog({ onClose }: EmailVerificationDialogProps) {
  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center">
      <div className="fixed inset-0 bg-black/50 backdrop-blur-sm" onClick={onClose} />
      <div className="relative z-10 w-full max-w-md rounded-xl bg-white p-6 shadow-2xl mx-4">
        <button
          type="button"
          onClick={onClose}
          className="absolute right-4 top-4 rounded-full p-1 text-gray-400 hover:bg-gray-100 hover:text-gray-600"
          aria-label="Close"
        >
          <X className="h-5 w-5" />
        </button>

        <div className="mb-4 flex h-12 w-12 items-center justify-center rounded-full bg-amber-100">
          <Mail className="h-6 w-6 text-amber-600" />
        </div>

        <h2 className="text-lg font-semibold text-gray-900">Verify your email</h2>
        <p className="mt-2 text-sm text-gray-600">
          To send emails or SMS messages through your agent, please verify your email address first.
        </p>

        <div className="mt-6 flex flex-col gap-3 sm:flex-row sm:justify-end">
          <button
            type="button"
            onClick={onClose}
            className="rounded-lg border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50"
          >
            Cancel
          </button>
          <a
            href="/accounts/email/"
            className="inline-flex items-center justify-center rounded-lg bg-indigo-600 px-4 py-2 text-sm font-medium text-white hover:bg-indigo-700"
          >
            Verify Email
          </a>
        </div>
      </div>
    </div>
  )
}

type LeaveCollaborationDialogProps = {
  agentName: string
  onClose: () => void
  onConfirm: () => Promise<void>
}

function LeaveCollaborationDialog({ agentName, onClose, onConfirm }: LeaveCollaborationDialogProps) {
  const [busy, setBusy] = useState(false)
  const [error, setError] = useState<string | null>(null)

  const handleConfirm = useCallback(async () => {
    if (busy) {
      return
    }
    setBusy(true)
    setError(null)
    try {
      await onConfirm()
      onClose()
    } catch (err) {
      console.error('Failed to leave collaboration', err)
      setError('Unable to leave this collaboration. Please try again.')
    } finally {
      setBusy(false)
    }
  }, [busy, onClose, onConfirm])

  return (
    <Modal
      title="Leave collaboration?"
      subtitle={`You will lose access to ${agentName}.`}
      icon={LogOut}
      iconBgClass="bg-rose-100"
      iconColorClass="text-rose-600"
      onClose={onClose}
      widthClass="sm:max-w-lg"
    >
      <div className="space-y-4">
        <p className="text-sm text-slate-600">
          Once you leave, you will no longer see this agent in your list or access its chat and files.
        </p>
        {error && (
          <div className="rounded-lg border border-rose-200 bg-rose-50 px-3 py-2 text-sm text-rose-700">
            {error}
          </div>
        )}
        <div className="flex flex-col gap-3 sm:flex-row sm:justify-end">
          <button
            type="button"
            onClick={onClose}
            disabled={busy}
            className="inline-flex items-center justify-center rounded-lg border border-slate-200 px-4 py-2 text-sm font-semibold text-slate-700 transition hover:border-slate-300 disabled:cursor-not-allowed disabled:opacity-60"
          >
            Cancel
          </button>
          <button
            type="button"
            onClick={handleConfirm}
            disabled={busy}
            className="inline-flex items-center justify-center rounded-lg bg-rose-600 px-4 py-2 text-sm font-semibold text-white transition hover:bg-rose-700 disabled:cursor-not-allowed disabled:opacity-60"
          >
            {busy ? 'Leaving...' : 'Leave Collaboration'}
          </button>
        </div>
      </div>
    </Modal>
  )
}

function buildSearchBlob(agent: AgentSummary): string {
  return buildAgentSearchBlob({
    name: agent.name,
    miniDescription: agent.miniDescription,
    listingDescription: agent.listingDescription,
    displayTags: agent.displayTags,
  })
}
