'use client'

import { useId, useState } from 'react'
import {
  AlertTriangle,
  CheckCircle2,
  ExternalLink,
  ImageIcon,
  Info,
  Loader2,
  RefreshCw,
  Search,
  Upload,
  X,
} from 'lucide-react'
import { MediaPickerModal } from '../../components/MediaPickerModal.js'
import { SEOConfigPanel } from '../../components/SEOConfigPanel.js'
import {
  ConfirmDangerousSettingDialog,
  SettingsCard,
  SettingsSaveBar,
  SettingsSourceBadge,
  SettingsToggleRow,
  SettingsValidationSummary,
} from './components.js'
import {
  META_DESCRIPTION_MAX,
  META_DESCRIPTION_MIN,
  useSeoSettings,
  validateTitleTemplateClient,
  type SeoSettingsForm,
  type UseSeoSettings,
} from './useSeoSettings.js'

const INPUT_CLASS =
  'w-full rounded-md border border-border bg-input-background px-3 py-2 text-base text-foreground focus-visible:ring-2 focus-visible:ring-ring focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-60'
const LABEL_CLASS = 'mb-1 flex items-center gap-2 text-sm font-medium text-foreground'

const SUPPORTED_TOKENS = [
  '%page%',
  '%site%',
  '%type%',
  '%separator%',
  '%author%',
  '%date%',
  '%category%',
  '%tag%',
]

/** Sample data used to render a live title preview. */
function previewTitle(template: string, siteName: string): string {
  const tpl = template.trim() === '' ? '%page% — %site%' : template
  const vars: Record<string, string> = {
    page: 'Sample Page Title',
    site: siteName || 'Your Site',
    type: 'Page',
    separator: '|',
    author: 'Jane Doe',
    date: new Date().toISOString().slice(0, 10),
    category: 'News',
    tag: 'guide',
  }
  return tpl
    .replace(/%(\w+)%/g, (_, k: string) => vars[k] ?? '')
    .replace(/\s+/g, ' ')
    .replace(/^[\s\-–—|·•]+/, '')
    .replace(/[\s\-–—|·•]+$/, '')
    .trim()
}

export interface SeoSettingsTabProps {
  onNavigate?: (path: string) => void
  /** Current user's role. Only ADMIN can persist changes. */
  role?: string
}

export function SeoSettingsTab({ onNavigate, role }: SeoSettingsTabProps) {
  const canEdit = role === 'ADMIN'
  const seo = useSeoSettings(canEdit)

  if (seo.loading) {
    return (
      <div className="space-y-4" aria-busy="true" aria-live="polite">
        <span className="sr-only">Loading SEO settings…</span>
        {[0, 1, 2, 3].map((i) => (
          <div key={i} className="border-border bg-card rounded-lg border p-6">
            <div className="bg-muted mb-4 h-4 w-40 animate-pulse rounded" />
            <div className="space-y-3">
              <div className="bg-muted h-9 w-full animate-pulse rounded" />
              <div className="bg-muted h-9 w-full animate-pulse rounded" />
            </div>
          </div>
        ))}
      </div>
    )
  }

  return (
    <div className="space-y-4">
      <SeoWorkspaceCallout onNavigate={onNavigate} />

      {seo.loadError && (
        <div
          role="alert"
          className="border-destructive/30 bg-destructive/10 text-destructive flex items-center gap-3 rounded-lg border p-3 text-sm"
        >
          <AlertTriangle size={16} className="shrink-0" aria-hidden="true" />
          <span className="flex-1">{seo.loadError}</span>
          <button
            type="button"
            onClick={seo.refetch}
            className="border-destructive/40 rounded-md border px-3 py-1 transition-colors hover:opacity-80"
          >
            Retry
          </button>
        </div>
      )}

      {!canEdit && (
        <div className="border-border bg-muted text-muted-foreground flex items-center gap-2 rounded-lg border p-3 text-sm">
          <Info size={16} className="shrink-0" aria-hidden="true" />
          You have read-only access to SEO defaults. Only administrators can make changes.
        </div>
      )}

      <SettingsValidationSummary issues={seo.issues} />

      <MetaDefaultsCard seo={seo} canEdit={canEdit} />
      <SearchEngineVerificationCard seo={seo} canEdit={canEdit} />
      <SitemapDefaultsCard seo={seo} canEdit={canEdit} onNavigate={onNavigate} />

      <details className="border-border bg-card group rounded-lg border">
        <summary className="text-foreground flex cursor-pointer list-none items-center justify-between p-4 text-base font-medium">
          <span>Advanced &amp; per-collection SEO</span>
          <span className="text-muted-foreground text-sm font-normal group-open:hidden">Show</span>
          <span className="text-muted-foreground hidden text-sm font-normal group-open:inline">
            Hide
          </span>
        </summary>
        <div className="border-border border-t p-4">
          <p className="text-muted-foreground mb-4 text-sm">
            Site name, social handle, per-collection schema, and route toggles. These share the same
            SEO configuration as the defaults above.
          </p>
          <SEOConfigPanel />
        </div>
      </details>

      {seo.saveState === 'error' && seo.saveError && (
        <div
          role="alert"
          className="border-destructive/30 bg-destructive/10 text-destructive flex items-center gap-3 rounded-lg border p-3 text-sm"
        >
          <AlertTriangle size={16} className="shrink-0" aria-hidden="true" />
          <span className="flex-1">{seo.saveError}</span>
          <button
            type="button"
            onClick={seo.save}
            className="border-destructive/40 rounded-md border px-3 py-1 transition-colors hover:opacity-80"
          >
            Retry
          </button>
        </div>
      )}

      <SettingsSaveBar
        dirty={seo.dirty}
        canEdit={canEdit}
        hasErrors={seo.hasErrors}
        saveState={seo.saveState}
        onSave={seo.save}
        onReset={seo.reset}
      />
    </div>
  )
}

// ---------------------------------------------------------------------------
// Full SEO workspace callout
// ---------------------------------------------------------------------------

function SeoWorkspaceCallout({ onNavigate }: { onNavigate?: (path: string) => void }) {
  return (
    <div className="border-border bg-accent/40 flex items-center gap-4 rounded-lg border p-4">
      <span className="bg-brand/10 text-brand flex h-10 w-10 shrink-0 items-center justify-center rounded-lg">
        <Search size={20} aria-hidden="true" />
      </span>
      <div className="flex-1">
        <p className="text-foreground text-base font-medium">Looking for the full SEO workspace?</p>
        <p className="text-muted-foreground text-sm">
          These are site-wide defaults. Per-page meta, audits, redirects and AI recovery live in the
          SEO dashboard.
        </p>
      </div>
      <button
        type="button"
        onClick={() => onNavigate?.('/seo')}
        className="border-border text-foreground hover:bg-accent inline-flex shrink-0 items-center gap-2 rounded-md border px-4 py-2 text-base font-medium transition-colors"
      >
        <ExternalLink size={16} aria-hidden="true" />
        Open SEO
      </button>
    </div>
  )
}

// ---------------------------------------------------------------------------
// Meta Defaults
// ---------------------------------------------------------------------------

function MetaDefaultsCard({ seo, canEdit }: { seo: UseSeoSettings; canEdit: boolean }) {
  const templateId = useId()
  const descId = useId()
  const [pickerOpen, setPickerOpen] = useState(false)

  const { form, setField, issues, sources } = seo
  const templateIssue = issues.find((i) => i.field === 'titleTemplate')
  const descIssue = issues.find((i) => i.field === 'defaultMetaDescription')
  const tplValidation = validateTitleTemplateClient(form.titleTemplate)

  const descLen = form.defaultMetaDescription.trim().length
  const descCountClass =
    descLen > META_DESCRIPTION_MAX || (descLen > 0 && descLen < META_DESCRIPTION_MIN)
      ? 'text-warning'
      : 'text-muted-foreground'

  const templateEditable = sources.titleTemplate?.editable !== false && canEdit
  const descEditable = sources.defaultMetaDescription?.editable !== false && canEdit
  const imageEditable = sources.defaultOgImage?.editable !== false && canEdit

  return (
    <SettingsCard
      title="Meta Defaults"
      description="Fallback page title, description, and social image applied when a page defines none of its own."
    >
      <div className="space-y-4">
        {/* Title template */}
        <div>
          <label htmlFor={templateId} className={LABEL_CLASS}>
            Title template
            <SettingsSourceBadge meta={sources.titleTemplate} />
          </label>
          <input
            id={templateId}
            type="text"
            value={form.titleTemplate}
            disabled={!templateEditable}
            placeholder="%page% — %site%"
            aria-invalid={templateIssue?.severity === 'error'}
            onChange={(e) => setField('titleTemplate', e.target.value)}
            className={INPUT_CLASS}
          />
          <p className="text-muted-foreground mt-1 text-sm">
            Tokens: {SUPPORTED_TOKENS.join(' ')}. Applied to all pages without a custom SEO title.
          </p>
          {templateIssue ? (
            <p className="text-destructive mt-1 text-sm">{templateIssue.message}</p>
          ) : (
            tplValidation.valid && (
              <p className="text-muted-foreground mt-1 text-sm">
                Preview:{' '}
                <span className="text-foreground font-medium">
                  {previewTitle(form.titleTemplate, seo.siteName)}
                </span>
              </p>
            )
          )}
        </div>

        {/* Default meta description */}
        <div>
          <label htmlFor={descId} className={LABEL_CLASS}>
            Default meta description
            <SettingsSourceBadge meta={sources.defaultMetaDescription} />
          </label>
          <textarea
            id={descId}
            rows={3}
            value={form.defaultMetaDescription}
            disabled={!descEditable}
            aria-describedby={`${descId}-count`}
            onChange={(e) => setField('defaultMetaDescription', e.target.value)}
            className={`${INPUT_CLASS} resize-y`}
          />
          <div className="mt-1 flex items-center justify-between gap-2">
            <p className="text-muted-foreground text-sm">
              Used when a page or post defines no description of its own.
            </p>
            <span id={`${descId}-count`} className={`text-sm ${descCountClass}`}>
              {descLen}/{META_DESCRIPTION_MAX}
            </span>
          </div>
          {descIssue && <p className="text-warning mt-1 text-sm">{descIssue.message}</p>}
        </div>

        {/* Default social share image */}
        <div>
          <span className={LABEL_CLASS}>
            Default social share image
            <SettingsSourceBadge meta={sources.defaultOgImage} />
          </span>
          <div className="flex items-center gap-3">
            <div className="border-border bg-muted flex h-16 w-28 shrink-0 items-center justify-center overflow-hidden rounded-md border">
              {form.defaultOgImage ? (
                // eslint-disable-next-line @next/next/no-img-element
                <img
                  src={form.defaultOgImage}
                  alt="Default social share preview"
                  className="h-full w-full object-cover"
                />
              ) : (
                <ImageIcon size={20} className="text-muted-foreground" aria-hidden="true" />
              )}
            </div>
            <div className="flex flex-col gap-2">
              <div className="flex items-center gap-2">
                <button
                  type="button"
                  onClick={() => setPickerOpen(true)}
                  disabled={!imageEditable}
                  className="border-border text-foreground hover:bg-accent inline-flex items-center gap-2 rounded-md border px-3 py-1.5 text-sm transition-colors disabled:cursor-not-allowed disabled:opacity-60"
                >
                  <Upload size={14} aria-hidden="true" />
                  {form.defaultOgImage ? 'Replace' : 'Choose image'}
                </button>
                {form.defaultOgImage && imageEditable && (
                  <button
                    type="button"
                    onClick={() => {
                      setField('defaultOgImage', '')
                      setField('defaultSocialImageAssetId', '')
                    }}
                    className="text-muted-foreground hover:text-destructive inline-flex items-center gap-1 rounded-md px-2 py-1.5 text-sm transition-colors"
                  >
                    <X size={14} aria-hidden="true" />
                    Remove
                  </button>
                )}
              </div>
              <p className="text-muted-foreground text-sm">1200×630 recommended</p>
            </div>
          </div>
        </div>
      </div>

      {/* SERP + social preview */}
      <SeoPreviewCard
        title={previewTitle(form.titleTemplate, seo.siteName)}
        url={seo.siteUrl || 'https://example.com'}
        description={
          form.defaultMetaDescription.trim() || 'Your default meta description appears here.'
        }
        image={form.defaultOgImage}
        siteName={seo.siteName}
      />

      <MediaPickerModal
        open={pickerOpen}
        onClose={() => setPickerOpen(false)}
        accept="image/*"
        onSelect={(url) => setField('defaultOgImage', url)}
        onSelectItem={(item) => setField('defaultSocialImageAssetId', item.id)}
      />
    </SettingsCard>
  )
}

function SeoPreviewCard({
  title,
  url,
  description,
  image,
  siteName,
}: {
  title: string
  url: string
  description: string
  image: string
  siteName: string
}) {
  return (
    <div className="border-border mt-4 grid gap-4 border-t pt-4 sm:grid-cols-2">
      <div className="border-border rounded-lg border p-3">
        <p className="text-muted-foreground mb-2 text-xs font-medium tracking-wide uppercase">
          Search preview
        </p>
        <p className="text-success truncate text-sm">{url}</p>
        <p className="text-primary truncate text-lg leading-snug">{title}</p>
        <p className="text-muted-foreground line-clamp-2 text-sm">{description}</p>
      </div>
      <div className="border-border overflow-hidden rounded-lg border">
        <div className="bg-muted flex aspect-1200/630 items-center justify-center">
          {image ? (
            // eslint-disable-next-line @next/next/no-img-element
            <img src={image} alt="Social share preview" className="h-full w-full object-cover" />
          ) : (
            <ImageIcon size={24} className="text-muted-foreground" aria-hidden="true" />
          )}
        </div>
        <div className="p-3">
          <p className="text-muted-foreground truncate text-xs uppercase">
            {siteName || new URL(url).hostname}
          </p>
          <p className="text-foreground truncate text-sm font-medium">{title}</p>
          <p className="text-muted-foreground line-clamp-1 text-xs">{description}</p>
        </div>
      </div>
    </div>
  )
}

// ---------------------------------------------------------------------------
// Search Engine Verification
// ---------------------------------------------------------------------------

function VerificationField({
  label,
  field,
  placeholder,
  value,
  onChange,
  disabled,
}: {
  label: string
  field: keyof SeoSettingsForm
  placeholder: string
  value: string
  onChange: (key: keyof SeoSettingsForm, value: string) => void
  disabled: boolean
}) {
  const id = useId()
  const hasValue = value.trim().length > 0
  return (
    <div>
      <label htmlFor={id} className={LABEL_CLASS}>
        {label}
        {hasValue && (
          <span className="text-muted-foreground border-border bg-muted inline-flex items-center gap-1 rounded-md border px-1.5 py-0.5 text-xs">
            <CheckCircle2 size={11} className="text-success" aria-hidden="true" />
            Saved
          </span>
        )}
      </label>
      <input
        id={id}
        type="text"
        autoComplete="off"
        spellCheck={false}
        value={value}
        disabled={disabled}
        placeholder={placeholder}
        onChange={(e) => onChange(field, e.target.value)}
        className={INPUT_CLASS}
      />
    </div>
  )
}

function SearchEngineVerificationCard({ seo, canEdit }: { seo: UseSeoSettings; canEdit: boolean }) {
  const { form, setField } = seo
  const onChange = (key: keyof SeoSettingsForm, value: string) => setField(key, value as never)

  return (
    <SettingsCard
      title="Search Engine Verification"
      description="Paste the verification token from each provider. We render only safe meta tags into your site's head — never arbitrary HTML."
    >
      <div className="space-y-4">
        <VerificationField
          label="Google Search Console"
          field="googleVerification"
          placeholder="google-site-verification…"
          value={form.googleVerification}
          onChange={onChange}
          disabled={!canEdit}
        />
        <VerificationField
          label="Bing Webmaster Tools"
          field="bingVerification"
          placeholder="msvalidate.01…"
          value={form.bingVerification}
          onChange={onChange}
          disabled={!canEdit}
        />
      </div>

      <details className="group mt-4">
        <summary className="text-brand cursor-pointer list-none text-sm hover:underline">
          <span className="group-open:hidden">More providers</span>
          <span className="hidden group-open:inline">Fewer providers</span>
        </summary>
        <div className="mt-4 space-y-4">
          <VerificationField
            label="Yandex"
            field="yandexVerification"
            placeholder="yandex-verification…"
            value={form.yandexVerification}
            onChange={onChange}
            disabled={!canEdit}
          />
          <VerificationField
            label="Pinterest"
            field="pinterestVerification"
            placeholder="p:domain_verify…"
            value={form.pinterestVerification}
            onChange={onChange}
            disabled={!canEdit}
          />
          <VerificationField
            label="Facebook domain verification"
            field="facebookDomainVerification"
            placeholder="facebook-domain-verification…"
            value={form.facebookDomainVerification}
            onChange={onChange}
            disabled={!canEdit}
          />
        </div>
      </details>
    </SettingsCard>
  )
}

// ---------------------------------------------------------------------------
// Sitemap Defaults
// ---------------------------------------------------------------------------

function SitemapDefaultsCard({
  seo,
  canEdit,
  onNavigate,
}: {
  seo: UseSeoSettings
  canEdit: boolean
  onNavigate?: (path: string) => void
}) {
  const [pendingDisable, setPendingDisable] = useState(false)
  const { form, setField, sitemap, siteUrl, isProduction, regenerateSitemap, regenerating } = seo

  function requestAutoGenerate(value: boolean) {
    // Turning auto-generation off on production can let the sitemap go stale.
    if (!value && isProduction) {
      setPendingDisable(true)
      return
    }
    setField('autoGenerateSitemap', value)
  }

  const lastGenerated = sitemap?.lastGeneratedAt
    ? new Date(sitemap.lastGeneratedAt).toLocaleString()
    : 'Never'

  return (
    <SettingsCard
      title="Sitemap"
      description="Control XML sitemap generation and whether search engines are pinged on publish."
    >
      {!siteUrl && (
        <div className="border-warning/30 bg-warning/10 text-warning mb-4 flex items-start gap-2 rounded-md border p-3 text-sm">
          <AlertTriangle size={16} className="mt-0.5 shrink-0" aria-hidden="true" />
          Site URL is not set — sitemap URLs may be incorrect. Set it in Settings → General.
        </div>
      )}

      <div className="space-y-4">
        <SettingsToggleRow
          label="Auto-generate XML sitemap"
          description="Rebuild the sitemap whenever content is published."
          checked={form.autoGenerateSitemap}
          disabled={!canEdit}
          onChange={requestAutoGenerate}
        />
        <SettingsToggleRow
          label="Ping search engines on publish"
          description="Notify Google and Bing when the sitemap changes."
          checked={form.pingOnPublish}
          disabled={!canEdit || !form.autoGenerateSitemap}
          onChange={(v) => setField('pingOnPublish', v)}
        />
      </div>

      <div className="border-border mt-4 space-y-2 border-t pt-4">
        <div className="flex items-center justify-between gap-2 text-sm">
          <span className="text-muted-foreground">Sitemap URL</span>
          {sitemap?.sitemapUrl ? (
            <a
              href={sitemap.sitemapUrl}
              target="_blank"
              rel="noreferrer"
              className="text-brand inline-flex items-center gap-1 font-medium hover:underline"
            >
              View sitemap
              <ExternalLink size={13} aria-hidden="true" />
            </a>
          ) : (
            <span className="text-foreground font-medium">/sitemap.xml</span>
          )}
        </div>
        <SummaryRow label="Last generated" value={lastGenerated} />
        <SummaryRow label="Included URLs" value={String(sitemap?.pagesIncluded ?? '—')} />
        <SummaryRow label="Excluded URLs" value={String(sitemap?.pagesExcluded ?? '—')} />
        <div className="flex items-center justify-between gap-2 pt-1">
          <button
            type="button"
            onClick={regenerateSitemap}
            disabled={!canEdit || regenerating}
            className="border-border text-foreground hover:bg-accent inline-flex items-center gap-2 rounded-md border px-3 py-1.5 text-sm transition-colors disabled:cursor-not-allowed disabled:opacity-60"
          >
            {regenerating ? (
              <Loader2 size={14} className="animate-spin" aria-hidden="true" />
            ) : (
              <RefreshCw size={14} aria-hidden="true" />
            )}
            Regenerate now
          </button>
          {onNavigate && (
            <button
              type="button"
              onClick={() => onNavigate('/seo?tab=technical')}
              className="text-brand text-sm hover:underline"
            >
              Manage in SEO Technical →
            </button>
          )}
        </div>
      </div>

      <ConfirmDangerousSettingDialog
        open={pendingDisable}
        title="Stop auto-generating the sitemap on production?"
        description="Your sitemap may go stale as content changes, which can hurt how quickly search engines discover new pages."
        confirmLabel="Turn Off"
        onConfirm={() => {
          setField('autoGenerateSitemap', false)
          setPendingDisable(false)
        }}
        onCancel={() => setPendingDisable(false)}
      />
    </SettingsCard>
  )
}

function SummaryRow({ label, value }: { label: string; value: string }) {
  return (
    <div className="flex items-center justify-between gap-2 text-sm">
      <span className="text-muted-foreground">{label}</span>
      <span className="text-foreground font-medium">{value}</span>
    </div>
  )
}
