'use client'

import { useEffect, useId, useState } from 'react'
import { RefreshCw, Map, AlertTriangle, CheckCircle2, ExternalLink, Bot } from 'lucide-react'
import * as Switch from '@radix-ui/react-switch'
import { toast } from 'sonner'
import {
  fetchSitemapStatus,
  regenerateSitemap,
  fetchCrawlSettings,
  updateCrawlSettings,
  fetchRobotsTxt,
  updateRobotsTxt,
  validateRobotsTxt,
  fetchAiCrawlerActivity,
  type CrawlSettings,
} from '../../lib/seo-service.js'
import {
  SectionCard,
  SeoLoading,
  SeoErrorState,
  btnPrimary,
  btnSecondary,
} from '../../components/seo/primitives.js'
import { useSeoResource } from './useSeoResource.js'

const CRAWL_TOGGLES: { key: keyof CrawlSettings; label: string; help: string }[] = [
  {
    key: 'indexEntireSite',
    label: 'Index entire site',
    help: 'Allow search engines to index all public pages.',
  },
  {
    key: 'includeImagesInSitemap',
    label: 'Include images in sitemap',
    help: 'Add image entries to the XML sitemap.',
  },
  {
    key: 'includePostsInSitemap',
    label: 'Include posts in sitemap',
    help: 'Add published posts to the sitemap.',
  },
]

function Toggle({
  checked,
  onChange,
  label,
  help,
  disabled,
}: {
  checked: boolean
  onChange: (v: boolean) => void
  label: string
  help: string
  disabled?: boolean
}) {
  const labelId = useId()
  const helpId = useId()
  return (
    <div className="flex items-center justify-between gap-3 py-2.5">
      <span className="min-w-0">
        <span id={labelId} className="text-foreground block text-sm font-medium">
          {label}
        </span>
        <span id={helpId} className="text-muted-foreground block text-sm">
          {help}
        </span>
      </span>
      <Switch.Root
        checked={checked}
        onCheckedChange={onChange}
        disabled={disabled}
        aria-labelledby={labelId}
        aria-describedby={helpId}
        className="bg-input-background data-[state=checked]:bg-primary focus-visible:ring-ring relative h-[18px] w-8 shrink-0 rounded-full transition-colors focus-visible:ring-2 focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50"
      >
        <Switch.Thumb className="bg-background block h-3.5 w-3.5 translate-x-0.5 rounded-full shadow-sm transition-transform data-[state=checked]:translate-x-[14px]" />
      </Switch.Root>
    </div>
  )
}

function SitemapCard() {
  const { data, loading, error, refetch } = useSeoResource(fetchSitemapStatus, [])
  const [busy, setBusy] = useState(false)

  async function handleRegenerate() {
    setBusy(true)
    const res = await regenerateSitemap()
    setBusy(false)
    if (res.error) {
      toast.error(res.error)
      return
    }
    toast.success('Sitemap regenerated.')
    refetch()
  }

  return (
    <SectionCard
      title="Sitemap"
      action={
        <button className={btnSecondary} onClick={handleRegenerate} disabled={busy || loading}>
          <RefreshCw className={`h-4 w-4 ${busy ? 'animate-spin' : ''}`} aria-hidden />
          Regenerate
        </button>
      }
    >
      {loading ? (
        <SeoLoading label="Loading sitemap status…" />
      ) : error ? (
        <SeoErrorState message={error} onRetry={refetch} />
      ) : !data ? (
        <p className="text-muted-foreground text-sm">Sitemap status unavailable.</p>
      ) : (
        <div className="space-y-3">
          <a
            href={data.sitemapUrl}
            target="_blank"
            rel="noopener noreferrer"
            className="text-primary inline-flex items-center gap-1 text-sm hover:underline"
          >
            <Map className="h-4 w-4" aria-hidden />
            {data.sitemapUrl}
            <ExternalLink className="h-3.5 w-3.5" aria-hidden />
          </a>
          <dl className="grid grid-cols-2 gap-3 text-sm">
            <div>
              <dt className="text-muted-foreground">Pages included</dt>
              <dd className="text-foreground font-medium tabular-nums">{data.pagesIncluded}</dd>
            </div>
            <div>
              <dt className="text-muted-foreground">Pages excluded</dt>
              <dd className="text-foreground font-medium tabular-nums">{data.pagesExcluded}</dd>
            </div>
            <div className="col-span-2">
              <dt className="text-muted-foreground">Last generated</dt>
              <dd className="text-foreground">
                {data.lastGeneratedAt ? new Date(data.lastGeneratedAt).toLocaleString() : 'Never'}
              </dd>
            </div>
          </dl>
          {data.warnings.length > 0 && (
            <ul className="space-y-1">
              {data.warnings.map((w, i) => (
                <li key={i} className="text-warning flex items-center gap-1.5 text-sm">
                  <AlertTriangle className="h-3.5 w-3.5" aria-hidden /> {w}
                </li>
              ))}
            </ul>
          )}
        </div>
      )}
    </SectionCard>
  )
}

function CrawlCard() {
  const { data, loading, error, refetch } = useSeoResource(fetchCrawlSettings, [])
  const [settings, setSettings] = useState<CrawlSettings | null>(null)
  const [saving, setSaving] = useState(false)

  useEffect(() => {
    if (data) setSettings(data)
  }, [data])

  async function save(next: CrawlSettings, changed: keyof CrawlSettings) {
    setSettings(next)
    setSaving(true)
    const res = await updateCrawlSettings({ [changed]: next[changed] })
    setSaving(false)
    if (res.error) {
      toast.error(res.error)
      refetch()
    }
  }

  return (
    <SectionCard title="Crawl Settings">
      {loading ? (
        <SeoLoading label="Loading crawl settings…" />
      ) : error ? (
        <SeoErrorState message={error} onRetry={refetch} />
      ) : !settings ? (
        <p className="text-muted-foreground text-sm">Crawl settings unavailable.</p>
      ) : (
        <div className="divide-border divide-y" aria-busy={saving}>
          {CRAWL_TOGGLES.map((t) => (
            <Toggle
              key={t.key}
              label={t.label}
              help={t.help}
              checked={settings[t.key]}
              disabled={saving}
              onChange={(v) => save({ ...settings, [t.key]: v }, t.key)}
            />
          ))}
        </div>
      )}
    </SectionCard>
  )
}

function RobotsCard() {
  const { data, loading, error, refetch } = useSeoResource(fetchRobotsTxt, [])
  const [body, setBody] = useState('')
  const [saving, setSaving] = useState(false)

  useEffect(() => {
    if (data) setBody(data.body)
  }, [data])

  const validation = validateRobotsTxt(body)

  async function handleSave() {
    setSaving(true)
    const res = await updateRobotsTxt(body)
    setSaving(false)
    if (res.error) {
      toast.error(res.error)
      return
    }
    toast.success('robots.txt saved.')
    refetch()
  }

  return (
    <SectionCard
      title="robots.txt"
      description="Controls which crawlers can access your site."
      action={
        <button
          className={btnPrimary}
          onClick={handleSave}
          disabled={saving || loading || !validation.valid}
        >
          {saving ? 'Saving…' : 'Save'}
        </button>
      }
    >
      {loading ? (
        <SeoLoading label="Loading robots.txt…" />
      ) : error ? (
        <SeoErrorState message={error} onRetry={refetch} />
      ) : (
        <div className="space-y-3">
          {validation.blocksEntireSite && (
            <div
              className="border-destructive/30 bg-destructive/10 flex items-start gap-2 rounded-md border p-3"
              role="alert"
            >
              <AlertTriangle className="text-destructive mt-0.5 h-4 w-4 shrink-0" aria-hidden />
              <p className="text-destructive text-sm">
                This configuration blocks your entire site from all search engines. Pages will be
                removed from search results.
              </p>
            </div>
          )}
          <label className="sr-only" htmlFor="robots-editor">
            robots.txt contents
          </label>
          <textarea
            id="robots-editor"
            value={body}
            onChange={(e) => setBody(e.target.value)}
            spellCheck={false}
            className="border-border bg-input-background text-foreground focus-visible:ring-ring min-h-48 w-full rounded-md border p-3 font-mono text-sm focus-visible:ring-2 focus-visible:outline-none"
          />
          {validation.errors.length > 0 ? (
            <ul className="space-y-1">
              {validation.errors.map((e, i) => (
                <li key={i} className="text-destructive flex items-center gap-1.5 text-sm">
                  <AlertTriangle className="h-3.5 w-3.5" aria-hidden /> {e}
                </li>
              ))}
            </ul>
          ) : (
            <p className="text-success flex items-center gap-1.5 text-sm">
              <CheckCircle2 className="h-3.5 w-3.5" aria-hidden /> Valid robots.txt
            </p>
          )}
          {validation.warnings
            .filter((w) => !validation.blocksEntireSite || !w.includes('blocks the entire site'))
            .map((w, i) => (
              <p key={i} className="text-warning flex items-center gap-1.5 text-sm">
                <AlertTriangle className="h-3.5 w-3.5" aria-hidden /> {w}
              </p>
            ))}
        </div>
      )}
    </SectionCard>
  )
}

const SURFACE_LABELS: Record<string, string> = {
  llms: 'llms.txt',
  'llms-full': 'llms-full.txt',
  md: '.md page',
  honeypot: 'honeypot',
}

const CATEGORY_LABELS: Record<string, string> = {
  training: 'Training',
  retrieval: 'Retrieval',
  other: 'Other',
}

function AiCrawlerCard() {
  const { data, loading, error, refetch } = useSeoResource(fetchAiCrawlerActivity, [])

  return (
    <SectionCard
      title="AI crawler activity"
      description="Known AI crawlers seen fetching llms.txt, llms-full.txt, and .md pages. This is visibility, not a traffic channel — expect modest numbers."
      action={
        <button className={btnSecondary} onClick={() => refetch()} disabled={loading}>
          <RefreshCw className={`h-4 w-4 ${loading ? 'animate-spin' : ''}`} aria-hidden />
          Refresh
        </button>
      }
    >
      {loading ? (
        <SeoLoading label="Loading crawler activity…" />
      ) : error ? (
        <SeoErrorState message={error} onRetry={refetch} />
      ) : !data || !data.enabled ? (
        <p className="text-muted-foreground text-sm">
          Crawler tracking is unavailable. Run the latest database migration to enable it.
        </p>
      ) : data.rows.length === 0 ? (
        <div className="flex flex-col items-center gap-2 py-8 text-center">
          <Bot className="text-muted-foreground h-6 w-6" aria-hidden />
          <p className="text-muted-foreground text-sm">No AI crawler activity recorded yet.</p>
        </div>
      ) : (
        <div className="space-y-4">
          <dl className="grid grid-cols-3 gap-3 text-sm">
            <div>
              <dt className="text-muted-foreground">Total hits</dt>
              <dd className="text-foreground font-medium tabular-nums">{data.totals.hits}</dd>
            </div>
            <div>
              <dt className="text-muted-foreground">Distinct bots</dt>
              <dd className="text-foreground font-medium tabular-nums">{data.totals.bots}</dd>
            </div>
            <div>
              <dt className="text-muted-foreground">Honeypot hits</dt>
              <dd className="text-foreground font-medium tabular-nums">{data.totals.honeypot}</dd>
            </div>
          </dl>
          <div className="overflow-x-auto">
            <table className="w-full text-sm" aria-label="AI crawler activity by bot">
              <thead>
                <tr className="border-border text-muted-foreground border-b text-left">
                  <th scope="col" className="py-2 pr-3 font-medium">
                    Bot
                  </th>
                  <th scope="col" className="py-2 pr-3 font-medium">
                    Type
                  </th>
                  <th scope="col" className="py-2 pr-3 font-medium">
                    Surface
                  </th>
                  <th scope="col" className="py-2 pr-3 text-right font-medium">
                    Hits
                  </th>
                  <th scope="col" className="py-2 font-medium">
                    Last seen
                  </th>
                </tr>
              </thead>
              <tbody className="divide-border divide-y">
                {data.rows.map((r) => (
                  <tr key={`${r.bot}:${r.surface}`}>
                    <td className="text-foreground py-2 pr-3 font-medium">{r.bot}</td>
                    <td className="text-muted-foreground py-2 pr-3">
                      {CATEGORY_LABELS[r.category] ?? r.category}
                    </td>
                    <td className="text-muted-foreground py-2 pr-3">
                      {SURFACE_LABELS[r.surface] ?? r.surface}
                    </td>
                    <td className="text-foreground py-2 pr-3 text-right tabular-nums">{r.hits}</td>
                    <td className="text-muted-foreground py-2">
                      {new Date(r.lastSeenAt).toLocaleDateString()}
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        </div>
      )}
    </SectionCard>
  )
}

export function TechnicalTab() {
  return (
    <div className="space-y-4">
      <div className="grid grid-cols-1 gap-4 lg:grid-cols-2">
        <SitemapCard />
        <CrawlCard />
      </div>
      <RobotsCard />
      <AiCrawlerCard />
    </div>
  )
}
