'use client'

import { Fragment, useMemo, useState } from 'react'
import { ClipboardCheck, Clock, CheckCircle2, FileDown, Sparkles } from 'lucide-react'
import { toast } from 'sonner'
import {
  fetchSeoIssues,
  fetchSeoAuditRuns,
  batchGenerateSeoContentBriefs,
  exportSeoFixBrief,
  isInlineSeoFixIssue,
  supportsSeoContentBrief,
  type SeoIssue,
  type SeoIssueQuery,
  type SeoSeverity,
  type SeoIssueStatus,
} from '../../lib/seo-service.js'
import {
  SectionCard,
  SeoLoading,
  SeoEmptyState,
  SeoErrorState,
  severityMeta,
  SeoStatusBadge,
  btnSecondary,
} from '../../components/seo/primitives.js'
import { SeoIssueFixDrawer } from '../../components/seo/SeoIssueFixDrawer.js'
import { SeoIssueFixPanel, SeoIssueFixToggle } from '../../components/seo/SeoIssueFixPanel.js'
import { PlanUpgradeCallout } from '../../components/PlanUpgradeCallout.js'
import { hasPlanFeature, type PlanInfo } from '../../lib/plan.js'
import { useSeoResource } from './useSeoResource.js'

const SEVERITY_FILTERS: { id: SeoSeverity | 'all'; label: string }[] = [
  { id: 'all', label: 'All' },
  { id: 'critical', label: 'Critical' },
  { id: 'warning', label: 'Warnings' },
  { id: 'info', label: 'Info' },
]

const STATUS_FILTERS: { id: SeoIssueStatus | 'all'; label: string }[] = [
  { id: 'open', label: 'Open' },
  { id: 'recurring', label: 'Recurring' },
  { id: 'ignored', label: 'Ignored' },
  { id: 'resolved', label: 'Resolved' },
  { id: 'all', label: 'All' },
]

function issueStatusTone(status: SeoIssueStatus) {
  switch (status) {
    case 'resolved':
      return 'good' as const
    case 'ignored':
      return 'neutral' as const
    case 'recurring':
      return 'fair' as const
    default:
      return 'critical' as const
  }
}

function AuditSummaryCards({ refetchKey }: { refetchKey: number }) {
  const { data, loading } = useSeoResource(fetchSeoAuditRuns, [refetchKey])
  const last = (data ?? [])[0]
  return (
    <div className="grid grid-cols-2 gap-4 lg:grid-cols-4">
      <div className="border-border bg-card rounded-lg border p-4">
        <p className="text-muted-foreground flex items-center gap-1.5 text-sm">
          <Clock className="h-3.5 w-3.5" aria-hidden /> Last audit
        </p>
        <p className="text-foreground mt-1 text-sm font-medium">
          {loading ? '…' : last ? new Date(last.startedAt).toLocaleString() : 'Never'}
        </p>
      </div>
      <div className="border-border bg-card rounded-lg border p-4">
        <p className="text-muted-foreground text-sm">Pages scanned</p>
        <p className="text-foreground mt-1 text-2xl font-medium tabular-nums">
          {last?.pagesScanned ?? 0}
        </p>
      </div>
      <div className="border-border bg-card rounded-lg border p-4">
        <p className="text-muted-foreground text-sm">Issues found</p>
        <p className="text-foreground mt-1 text-2xl font-medium tabular-nums">
          {last?.issuesFound ?? 0}
        </p>
      </div>
      <div className="border-border bg-card rounded-lg border p-4">
        <p className="text-muted-foreground text-sm">Site score</p>
        <p className="text-foreground mt-1 text-2xl font-medium tabular-nums">
          {last?.siteScoreAfter ?? '—'}
        </p>
      </div>
    </div>
  )
}

export function AuditTab({
  refetchKey = 0,
  initialIssueId,
  onNavigate,
  planInfo,
}: {
  refetchKey?: number
  initialIssueId?: string | null
  onNavigate?: (path: string) => void
  planInfo?: PlanInfo | null
}) {
  const [severity, setSeverity] = useState<SeoSeverity | 'all'>('all')
  const [status, setStatus] = useState<SeoIssueStatus | 'all'>('open')
  const [expandedIssueId, setExpandedIssueId] = useState<string | null>(initialIssueId ?? null)
  const [detailIssueId, setDetailIssueId] = useState<string | null>(null)
  const [exportingBrief, setExportingBrief] = useState(false)
  const [batchGenerating, setBatchGenerating] = useState(false)

  const query: SeoIssueQuery = useMemo(() => ({ severity, status }), [severity, status])
  const { data, loading, error, refetch } = useSeoResource(
    () => fetchSeoIssues(query),
    [severity, status, refetchKey],
  )

  const issues = data ?? []

  const briefEligibleCount = useMemo(
    () => issues.filter((i) => supportsSeoContentBrief(i.type)).length,
    [issues],
  )
  const batchBriefsEnabled = hasPlanFeature(planInfo, 'seo.batchContentBriefs')

  function toggleExpanded(issueId: string) {
    setExpandedIssueId((current) => (current === issueId ? null : issueId))
  }

  function handleChanged() {
    setExpandedIssueId(null)
    refetch()
  }

  async function handleBatchGenerateBriefs() {
    const issueIds = issues.filter((i) => supportsSeoContentBrief(i.type)).map((i) => i.id)
    if (issueIds.length === 0) {
      toast.message('No content-brief issues in the current list.')
      return
    }
    setBatchGenerating(true)
    try {
      const res = await batchGenerateSeoContentBriefs({
        severity,
        status,
        issueIds,
        skipExisting: true,
      })
      if (res.error || !res.data) {
        toast.error(res.error ?? 'Batch generation failed.')
        return
      }
      const { generated, skipped, failed } = res.data
      if (generated === 0 && failed === 0) {
        toast.message(`All ${skipped} brief(s) already cached for the current filters.`)
      } else {
        toast.success(
          `Generated ${generated} brief(s)${skipped ? `, skipped ${skipped} cached` : ''}${failed ? `, ${failed} failed` : ''}.`,
        )
      }
      refetch()
    } finally {
      setBatchGenerating(false)
    }
  }

  async function handleExportBrief() {
    setExportingBrief(true)
    try {
      const res = await exportSeoFixBrief({ severity, status, manualOnly: true })
      if (res.error || !res.data?.markdown) {
        toast.error(res.error ?? 'Export failed.')
        return
      }
      const blob = new Blob([res.data.markdown], { type: 'text/markdown;charset=utf-8' })
      const url = URL.createObjectURL(blob)
      const link = document.createElement('a')
      link.href = url
      link.download = res.data.filename || 'seo-fix-brief.md'
      document.body.appendChild(link)
      link.click()
      document.body.removeChild(link)
      setTimeout(() => URL.revokeObjectURL(url), 0)
      if (res.data.issueCount === 0) {
        toast.message('Brief downloaded — no manual fixes matched the current filters.')
      } else {
        toast.success(`Exported ${res.data.issueCount} manual fix(es) for your dev team.`)
      }
    } finally {
      setExportingBrief(false)
    }
  }

  return (
    <div className="space-y-4">
      <AuditSummaryCards refetchKey={refetchKey} />

      <SectionCard>
        <div className="mb-4 flex flex-col gap-3 lg:flex-row lg:items-start lg:justify-between">
          <div className="flex flex-col gap-3 sm:flex-row sm:flex-wrap sm:items-center">
            <div className="flex flex-wrap gap-1" role="group" aria-label="Filter by severity">
              {SEVERITY_FILTERS.map((f) => (
                <button
                  key={f.id}
                  type="button"
                  aria-pressed={severity === f.id}
                  onClick={() => setSeverity(f.id)}
                  className={`focus-visible:ring-ring rounded-md px-3 py-1.5 text-sm font-medium transition-colors focus-visible:ring-2 focus-visible:outline-none ${
                    severity === f.id
                      ? 'bg-primary text-primary-foreground'
                      : 'text-muted-foreground hover:bg-accent hover:text-foreground'
                  }`}
                >
                  {f.label}
                </button>
              ))}
            </div>
            <div className="flex flex-wrap gap-1" role="group" aria-label="Filter by status">
              {STATUS_FILTERS.map((f) => (
                <button
                  key={f.id}
                  type="button"
                  aria-pressed={status === f.id}
                  onClick={() => setStatus(f.id)}
                  className={`focus-visible:ring-ring rounded-md px-3 py-1.5 text-sm font-medium transition-colors focus-visible:ring-2 focus-visible:outline-none ${
                    status === f.id
                      ? 'bg-accent text-foreground'
                      : 'text-muted-foreground hover:bg-accent hover:text-foreground'
                  }`}
                >
                  {f.label}
                </button>
              ))}
            </div>
          </div>
          <div className="flex flex-wrap gap-2">
            {batchBriefsEnabled ? (
              <button
                type="button"
                className={btnSecondary}
                onClick={handleBatchGenerateBriefs}
                disabled={batchGenerating || loading || briefEligibleCount === 0}
                aria-busy={batchGenerating}
              >
                <Sparkles className="h-4 w-4" aria-hidden />
                {batchGenerating ? 'Generating…' : 'Generate briefs'}
              </button>
            ) : (
              <PlanUpgradeCallout
                feature="seo.batchContentBriefs"
                upgradeUrl={planInfo?.upgradeUrl}
              />
            )}
            <button
              type="button"
              className={btnSecondary}
              onClick={handleExportBrief}
              disabled={exportingBrief || loading}
              aria-busy={exportingBrief}
            >
              <FileDown className="h-4 w-4" aria-hidden />
              {exportingBrief ? 'Exporting…' : 'Export fix brief'}
            </button>
          </div>
        </div>

        {loading ? (
          <SeoLoading label="Loading issues…" />
        ) : error ? (
          <SeoErrorState message={error} onRetry={refetch} />
        ) : issues.length === 0 ? (
          <SeoEmptyState
            icon={status === 'open' ? <CheckCircle2 size={24} /> : <ClipboardCheck size={24} />}
            title={status === 'open' ? 'No open issues' : 'No issues match'}
            description={
              status === 'open'
                ? 'Run an audit to scan for new issues, or adjust the filters.'
                : 'Try a different severity or status filter.'
            }
          />
        ) : (
          <div className="overflow-x-auto">
            <table className="w-full min-w-[680px] text-sm" aria-label="SEO issues">
              <thead>
                <tr className="text-muted-foreground border-border border-b text-left">
                  <th className="py-2 pr-4 font-medium">Severity</th>
                  <th className="py-2 pr-4 font-medium">Issue</th>
                  <th className="py-2 pr-4 font-medium">Page</th>
                  <th className="py-2 pr-4 font-medium">Status</th>
                  <th className="py-2 text-right font-medium">
                    <span className="sr-only">Actions</span>
                  </th>
                </tr>
              </thead>
              <tbody className="divide-border divide-y">
                {issues.map((issue: SeoIssue) => {
                  const meta = severityMeta(issue.severity)
                  const expanded = expandedIssueId === issue.id
                  return (
                    <Fragment key={issue.id}>
                      <tr className={`hover:bg-accent/40 ${expanded ? 'bg-accent/20' : ''}`}>
                        <td className="py-2.5 pr-4">
                          <span className={`inline-flex items-center gap-1.5 text-sm ${meta.text}`}>
                            <span className={`h-1.5 w-1.5 rounded-full ${meta.dot}`} aria-hidden />
                            {meta.label}
                          </span>
                        </td>
                        <td className="py-2.5 pr-4">
                          <span className="text-foreground block font-medium">{issue.title}</span>
                          <span className="text-muted-foreground block capitalize">
                            {issue.category}
                          </span>
                        </td>
                        <td className="text-muted-foreground py-2.5 pr-4">
                          <span className="block truncate">
                            {issue.entityTitle || issue.url || '—'}
                          </span>
                        </td>
                        <td className="py-2.5 pr-4">
                          <SeoStatusBadge
                            label={issue.status}
                            tone={issueStatusTone(issue.status)}
                          />
                        </td>
                        <td className="py-2.5 text-right">
                          <SeoIssueFixToggle
                            expanded={expanded}
                            fixable={
                              issue.fixable ||
                              isInlineSeoFixIssue(issue.type) ||
                              supportsSeoContentBrief(issue.type)
                            }
                            onToggle={() => toggleExpanded(issue.id)}
                          />
                        </td>
                      </tr>
                      <SeoIssueFixPanel
                        issue={issue}
                        expanded={expanded}
                        onChanged={handleChanged}
                        onNavigate={onNavigate}
                        onOpenDetails={() => setDetailIssueId(issue.id)}
                        planInfo={planInfo}
                      />
                    </Fragment>
                  )
                })}
              </tbody>
            </table>
          </div>
        )}
      </SectionCard>

      <SeoIssueFixDrawer
        open={detailIssueId !== null}
        onOpenChange={(o) => !o && setDetailIssueId(null)}
        issueId={detailIssueId}
        onChanged={handleChanged}
        onNavigate={onNavigate}
      />
    </div>
  )
}
