'use client'

import {
  Calendar,
  Check,
  ExternalLink,
  Eye,
  Globe,
  History,
  Laptop,
  Loader2,
  type LucideIcon,
  Monitor,
  Settings2,
  Smartphone,
  Tablet,
  TriangleAlert,
} from 'lucide-react'
import { EditorSeoScoreBadge } from '../../components/seo/EditorSeoScoreBadge.js'
import type { PageStatus } from '../../lib/page-editor-service.js'
import { VIEWPORTS, type ViewportId } from './viewports.js'

export type SaveState = 'idle' | 'saving' | 'saved' | 'error'

interface EditorTopBarProps {
  title: string
  status: PageStatus
  dirty: boolean
  saveState: SaveState
  publishing: boolean
  canEdit: boolean
  canPublish: boolean
  /** When false, Publish stays disabled even if the user has publish permission. */
  publishReady?: boolean
  /** Shown on hover/focus when publish is blocked by validation (not role). */
  publishDisabledReason?: string
  viewport: ViewportId
  /** Breadcrumb root label + back-button text (e.g. "Pages" or "Posts"). */
  backLabel?: string
  onViewport: (v: ViewportId) => void
  onBack: () => void
  onPreview: () => void
  /**
   * Open the draft on the public site (real front-end) in a new tab. When
   * omitted the "View on site" button is hidden — e.g. for unsaved documents
   * or installs without a public URL.
   */
  onViewOnSite?: () => void
  /**
   * Open the version history panel. When omitted the History button is
   * hidden — e.g. for unsaved documents that have no versions yet.
   */
  onHistory?: () => void
  /** Whether the inline site preview (iframe of the public site) is showing. */
  sitePreview?: boolean
  /**
   * Toggle the inline site preview — renders the draft through the consumer's
   * real public route inside the editor. Hidden when omitted (unsaved docs).
   */
  onToggleSitePreview?: () => void
  onOpenSettings: () => void
  /** Open the document SEO panel (meta, social, schema, analysis). */
  onOpenSeo?: () => void
  seoOpen?: boolean
  /** Live 0–100 SEO score shown left of the SEO label. */
  seoScore?: number
  onSaveDraft: () => void
  onPublish: () => void
  /** Open the schedule-publish dialog. Omitted when the document is unsaved. */
  onSchedule?: () => void
  /** When false, Schedule stays disabled (e.g. unsaved document). Defaults to true. */
  scheduleReady?: boolean
  scheduledAt?: string | null
  scheduledUnpublishAt?: string | null
  /**
   * Section types the canvas renders as placeholders (custom / unmanaged).
   * When non-empty the editor is in "structure" mode: the eye preview is
   * labeled as a structure preview and "View on site" is promoted to a
   * labeled button as the primary design preview.
   */
  structuralTypes?: string[]
}

const VIEWPORT_ICONS: Record<string, LucideIcon> = {
  monitor: Monitor,
  laptop: Laptop,
  tablet: Tablet,
  smartphone: Smartphone,
}

const STATUS_TEXT: Record<PageStatus, { label: string; className: string }> = {
  DRAFT: { label: 'Draft', className: 'text-warning dark:text-amber-400' },
  PUBLISHED: { label: 'Published', className: 'text-emerald-600 dark:text-emerald-400' },
  SCHEDULED: { label: 'Scheduled', className: 'text-warning dark:text-amber-400' },
  ARCHIVED: { label: 'Archived', className: 'text-muted-foreground' },
}

export function EditorTopBar({
  title,
  status,
  dirty,
  saveState,
  publishing,
  canEdit,
  canPublish,
  publishReady = true,
  publishDisabledReason,
  viewport,
  backLabel = 'Pages',
  onViewport,
  onBack,
  onPreview,
  onViewOnSite,
  onHistory,
  sitePreview = false,
  onToggleSitePreview,
  onOpenSettings,
  onOpenSeo,
  seoOpen = false,
  seoScore = 0,
  onSaveDraft,
  onPublish,
  onSchedule,
  scheduleReady = true,
  scheduledAt = null,
  scheduledUnpublishAt = null,
  structuralTypes = [],
}: EditorTopBarProps) {
  const statusInfo = STATUS_TEXT[status]
  // With custom section types on the page the canvas (and the eye preview,
  // which reuses the admin renderers) only shows structure — the real design
  // preview is the public site, so promote "View on site" to a labeled button.
  const structural = structuralTypes.length > 0
  const previewLabel = structural
    ? 'Preview structure (custom sections show placeholders)'
    : 'Preview page'

  const publishBlocked = !canPublish || !publishReady || publishing || saveState === 'saving'
  const publishTitle = publishing
    ? 'Publishing…'
    : saveState === 'saving'
      ? 'Wait for the current save to finish'
      : canPublish && !publishReady && publishDisabledReason
        ? publishDisabledReason
        : !canPublish
          ? 'You do not have permission to publish'
          : undefined

  const scheduleBlocked =
    !onSchedule ||
    !canPublish ||
    !publishReady ||
    !scheduleReady ||
    publishing ||
    saveState === 'saving'
  const scheduleTitle =
    saveState === 'saving'
      ? 'Wait for the current save to finish'
      : !scheduleReady
        ? 'Save before scheduling'
        : canPublish && !publishReady && publishDisabledReason
          ? publishDisabledReason
          : !canPublish
            ? 'You do not have permission to schedule'
            : scheduledAt
              ? `Reschedule — currently publishes ${formatScheduleLabel(scheduledAt)}`
              : 'Schedule a future publish date'

  return (
    <header className="bg-card border-border flex h-14 shrink-0 items-center justify-between gap-4 border-b px-4">
      {/* Breadcrumb + status */}
      <div className="flex min-w-0 items-center gap-2">
        <nav aria-label="Breadcrumb" className="flex min-w-0 items-center gap-1.5 text-sm">
          <button
            type="button"
            onClick={onBack}
            className="text-muted-foreground hover:text-foreground shrink-0"
          >
            {backLabel}
          </button>
          <span className="text-muted-foreground" aria-hidden>
            /
          </span>
          <span className="text-foreground truncate font-medium">{title || 'Untitled page'}</span>
        </nav>
        <span
          className={`ml-2 shrink-0 text-xs font-medium ${statusInfo.className}`}
          aria-label={`Status: ${statusInfo.label}`}
        >
          {statusInfo.label}
        </span>
        {scheduledAt && (
          <span
            className="text-muted-foreground ml-1 hidden shrink-0 text-xs sm:inline"
            title={
              scheduledUnpublishAt
                ? `Publishes ${formatScheduleLabel(scheduledAt)} · Unpublishes ${formatScheduleLabel(scheduledUnpublishAt)}`
                : `Publishes ${formatScheduleLabel(scheduledAt)}`
            }
          >
            · {formatScheduleLabel(scheduledAt)}
          </span>
        )}
        <SaveStatus state={saveState} dirty={dirty} />
      </div>

      {/* Right controls */}
      <div className="flex items-center gap-2">
        <div
          className="border-border bg-background hidden items-center gap-0.5 rounded-lg border p-0.5 md:flex"
          role="group"
          aria-label="Preview viewport"
        >
          {VIEWPORTS.map((v) => {
            const Icon = VIEWPORT_ICONS[v.icon] ?? Monitor
            const active = v.id === viewport
            return (
              <button
                key={v.id}
                type="button"
                onClick={() => onViewport(v.id)}
                aria-pressed={active}
                title={`${v.label} (${v.width}px)`}
                className={`flex items-center gap-1 rounded-md px-2 py-1 text-xs font-medium transition-colors ${
                  active
                    ? 'bg-primary text-primary-foreground'
                    : 'text-muted-foreground hover:text-foreground hover:bg-accent'
                }`}
              >
                <Icon className="h-3.5 w-3.5" aria-hidden />
                <span className="hidden lg:inline">{v.label}</span>
              </button>
            )
          })}
        </div>

        <button
          type="button"
          onClick={onOpenSettings}
          aria-label="Page settings"
          title="Page settings"
          className="text-muted-foreground hover:text-foreground hover:bg-accent rounded-lg p-2"
        >
          <Settings2 className="h-4 w-4" aria-hidden />
        </button>

        {onOpenSeo && (
          <button
            type="button"
            onClick={onOpenSeo}
            aria-pressed={seoOpen}
            aria-label={`SEO, score ${seoScore} out of 100`}
            title={`SEO — score ${seoScore}/100. Meta tags, social preview, schema, and analysis.`}
            className={`inline-flex items-center gap-1.5 rounded-lg px-2 py-1.5 text-sm font-medium transition-colors ${
              seoOpen
                ? 'bg-primary text-primary-foreground'
                : 'text-muted-foreground hover:text-foreground hover:bg-accent'
            }`}
          >
            <EditorSeoScoreBadge score={seoScore} inverted={seoOpen} />
            <span className="hidden sm:inline">SEO</span>
          </button>
        )}

        {onHistory && (
          <button
            type="button"
            onClick={onHistory}
            aria-label="Version history"
            title="Version history"
            className="text-muted-foreground hover:text-foreground hover:bg-accent rounded-lg p-2"
          >
            <History className="h-4 w-4" aria-hidden />
          </button>
        )}

        <button
          type="button"
          onClick={onPreview}
          aria-label={previewLabel}
          title={previewLabel}
          className="text-muted-foreground hover:text-foreground hover:bg-accent rounded-lg p-2"
        >
          <Eye className="h-4 w-4" aria-hidden />
        </button>

        {onToggleSitePreview && (
          <button
            type="button"
            onClick={onToggleSitePreview}
            aria-pressed={sitePreview}
            aria-label={sitePreview ? 'Back to editor canvas' : 'Inline site preview'}
            title={
              sitePreview
                ? 'Back to editor canvas'
                : 'Inline site preview — render the draft through your public site, in place'
            }
            className={`rounded-lg p-2 transition-colors ${
              sitePreview
                ? 'bg-primary text-primary-foreground'
                : 'text-muted-foreground hover:text-foreground hover:bg-accent'
            }`}
          >
            <Globe className="h-4 w-4" aria-hidden />
          </button>
        )}

        {onViewOnSite &&
          (structural ? (
            <button
              type="button"
              onClick={onViewOnSite}
              title="Open the draft on your public site — the real design preview"
              className="border-border text-foreground hover:bg-accent inline-flex items-center gap-1.5 rounded-lg border px-3 py-1.5 text-sm font-medium transition-colors"
            >
              <ExternalLink className="h-3.5 w-3.5" aria-hidden />
              View on site
            </button>
          ) : (
            <button
              type="button"
              onClick={onViewOnSite}
              aria-label="View draft on site"
              title="View draft on site"
              className="text-muted-foreground hover:text-foreground hover:bg-accent rounded-lg p-2"
            >
              <ExternalLink className="h-4 w-4" aria-hidden />
            </button>
          ))}

        <button
          type="button"
          onClick={onSaveDraft}
          disabled={!canEdit || saveState === 'saving' || (!dirty && saveState !== 'error')}
          className="border-border text-foreground hover:bg-accent rounded-lg border px-3 py-1.5 text-sm font-medium transition-colors disabled:cursor-not-allowed disabled:opacity-50"
        >
          {saveState === 'saving' ? 'Saving…' : 'Save Draft'}
        </button>

        {onSchedule && (
          <button
            type="button"
            onClick={onSchedule}
            disabled={scheduleBlocked}
            title={scheduleTitle}
            aria-label={scheduledAt ? 'Reschedule publish' : 'Schedule publish'}
            className="border-border text-foreground hover:bg-accent inline-flex items-center gap-1.5 rounded-lg border px-3 py-1.5 text-sm font-medium transition-colors disabled:cursor-not-allowed disabled:opacity-50"
          >
            <Calendar className="h-3.5 w-3.5" aria-hidden />
            <span className="hidden sm:inline">{scheduledAt ? 'Reschedule' : 'Schedule'}</span>
          </button>
        )}

        <button
          type="button"
          onClick={onPublish}
          disabled={publishBlocked}
          title={publishTitle}
          aria-disabled={publishBlocked}
          className="bg-primary text-primary-foreground hover:bg-primary/90 inline-flex items-center gap-1.5 rounded-lg px-3.5 py-1.5 text-sm font-medium transition-colors disabled:cursor-not-allowed disabled:opacity-50"
        >
          {publishing && <Loader2 className="h-3.5 w-3.5 animate-spin" aria-hidden />}
          Publish
        </button>
      </div>
    </header>
  )
}

function SaveStatus({ state, dirty }: { state: SaveState; dirty: boolean }) {
  if (state === 'saving') {
    return (
      <span
        className="text-muted-foreground ml-2 inline-flex items-center gap-1 text-xs"
        aria-live="polite"
      >
        <Loader2 className="h-3 w-3 animate-spin" aria-hidden />
        Saving…
      </span>
    )
  }
  if (state === 'error') {
    return (
      <span
        className="text-destructive ml-2 inline-flex items-center gap-1 text-xs"
        aria-live="polite"
      >
        <TriangleAlert className="h-3 w-3" aria-hidden />
        Failed to save
      </span>
    )
  }
  if (dirty) {
    return (
      <span className="text-muted-foreground ml-2 text-xs" aria-live="polite">
        Unsaved changes
      </span>
    )
  }
  if (state === 'saved') {
    return (
      <span
        className="text-muted-foreground ml-2 inline-flex items-center gap-1 text-xs"
        aria-live="polite"
      >
        <Check className="h-3 w-3" aria-hidden />
        Saved
      </span>
    )
  }
  return null
}

function formatScheduleLabel(iso: string): string {
  const d = new Date(iso)
  if (Number.isNaN(d.getTime())) return iso
  return d.toLocaleString(undefined, {
    month: 'short',
    day: 'numeric',
    year: 'numeric',
    hour: 'numeric',
    minute: '2-digit',
  })
}
