'use client'

import { useState } from 'react'
import { Check, Copy, Link2, Loader2, Share2, X } from 'lucide-react'
import { toast } from 'sonner'
import { cmsApi } from '../lib/api.js'

export interface SharePreviewLinkDialogProps {
  collectionSlug: string
  documentId: string
  /** Document slug, used to build a friendly preview URL. */
  documentSlug?: string | null
  /**
   * Optional site URL (https://...) to prepend. If omitted we just emit the
   * relative path and ask the admin to share it however they want.
   */
  siteUrl?: string
  /** Custom URL prefix for this collection (e.g. /blog). Defaults to slug. */
  urlPrefix?: string
  open: boolean
  onClose: () => void
}

interface TTLChoice {
  label: string
  seconds: number
  hint: string
}

const TTL_CHOICES: TTLChoice[] = [
  { label: '1 hour', seconds: 60 * 60, hint: 'Quick review' },
  { label: '1 day', seconds: 24 * 60 * 60, hint: 'Single workday' },
  { label: '7 days', seconds: 7 * 24 * 60 * 60, hint: 'Client review' },
  { label: '30 days', seconds: 30 * 24 * 60 * 60, hint: 'Long-running staging' },
]

function buildPreviewUrl({
  siteUrl,
  urlPrefix,
  collectionSlug,
  documentSlug,
  token,
}: {
  siteUrl?: string
  urlPrefix?: string
  collectionSlug: string
  documentSlug?: string | null
  token: string
}): string {
  const base = (siteUrl ?? '').replace(/\/+$/, '')
  // Build the same path /resolve would match: <urlPrefix>/<slug>, or
  // /<slug> for top-level page collections. If there's no slug yet we
  // fall back to /admin's preview endpoint as a safety net.
  const slug = documentSlug?.toString().trim() ?? ''
  if (!slug) {
    return `${base}/preview/${collectionSlug}/_?token=${encodeURIComponent(token)}`
  }
  const prefix = (urlPrefix ?? collectionSlug).replace(/^\/+|\/+$/g, '')
  const path = prefix ? `/${prefix}/${slug}` : `/${slug}`
  return `${base}${path}?preview=${encodeURIComponent(token)}`
}

export function SharePreviewLinkDialog({
  collectionSlug,
  documentId,
  documentSlug,
  siteUrl,
  urlPrefix,
  open,
  onClose,
}: SharePreviewLinkDialogProps) {
  const [ttl, setTtl] = useState<number>(TTL_CHOICES[2]!.seconds)
  const [token, setToken] = useState<string>('')
  const [previewUrl, setPreviewUrl] = useState<string>('')
  const [expiresAt, setExpiresAt] = useState<string>('')
  const [generating, setGenerating] = useState(false)
  const [copied, setCopied] = useState(false)

  async function generate() {
    setGenerating(true)
    const res = await cmsApi<{
      token: string
      expiresAt: string
      slug?: string | null
    }>('/preview/token', {
      method: 'POST',
      body: JSON.stringify({
        collection: collectionSlug,
        documentId,
        ttlSeconds: ttl,
      }),
    })
    setGenerating(false)
    if (res.error || !res.data) {
      toast.error(res.error ?? 'Failed to create preview token')
      return
    }
    const data = res.data
    setToken(data.token)
    setExpiresAt(data.expiresAt ?? '')
    const url = buildPreviewUrl({
      siteUrl,
      urlPrefix,
      collectionSlug,
      documentSlug: data.slug ?? documentSlug,
      token: data.token,
    })
    setPreviewUrl(url)
    setCopied(false)
  }

  async function copyToClipboard() {
    if (!previewUrl) return
    try {
      await navigator.clipboard.writeText(previewUrl)
      setCopied(true)
      toast.success('Preview link copied')
      setTimeout(() => setCopied(false), 2000)
    } catch {
      toast.error("Couldn't copy to clipboard")
    }
  }

  if (!open) return null

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center p-4">
      <div className="fixed inset-0 bg-black/40" onClick={onClose} />
      <div className="relative w-full max-w-lg rounded-lg bg-white shadow-xl">
        <div className="flex items-center justify-between border-b border-gray-200 px-4 py-3">
          <div className="flex items-center gap-2">
            <Share2 className="h-5 w-5 text-gray-600" />
            <h2 className="text-lg font-semibold text-gray-900">Share preview link</h2>
          </div>
          <button
            onClick={onClose}
            className="rounded-lg p-1.5 transition-colors hover:bg-gray-100"
          >
            <X className="h-5 w-5 text-gray-500" />
          </button>
        </div>

        <div className="space-y-4 px-4 py-4">
          <p className="text-sm text-gray-600">
            Generate a signed URL that lets anyone with the link view the current draft of this
            document — even if it's never been published.
          </p>

          <div className="space-y-2">
            <label className="text-sm font-medium text-gray-700">Link lifetime</label>
            <div className="grid grid-cols-2 gap-2">
              {TTL_CHOICES.map((choice) => {
                const selected = ttl === choice.seconds
                return (
                  <button
                    key={choice.seconds}
                    onClick={() => setTtl(choice.seconds)}
                    className={`rounded-md border px-3 py-2 text-left text-sm transition-colors ${
                      selected
                        ? 'border-blue-500 bg-blue-50 text-blue-900'
                        : 'border-gray-200 hover:border-gray-300 hover:bg-gray-50'
                    }`}
                  >
                    <div className="font-medium">{choice.label}</div>
                    <div className="text-xs text-gray-500">{choice.hint}</div>
                  </button>
                )
              })}
            </div>
            <p className="text-xs text-gray-500">
              Preview tokens can't be revoked individually — pick the shortest TTL that fits.
            </p>
          </div>

          {previewUrl ? (
            <div className="space-y-2 rounded-lg border border-gray-200 bg-gray-50 p-3">
              <label className="text-xs font-medium tracking-wide text-gray-500 uppercase">
                Preview URL
              </label>
              <div className="flex items-stretch gap-2">
                <input
                  readOnly
                  value={previewUrl}
                  onFocus={(e) => e.currentTarget.select()}
                  className="flex-1 rounded-md border border-gray-300 bg-white px-2 py-1.5 font-mono text-xs"
                />
                <button
                  onClick={copyToClipboard}
                  className="inline-flex items-center gap-1.5 rounded-md bg-gray-900 px-3 py-1.5 text-xs font-medium text-white hover:bg-gray-700"
                >
                  {copied ? <Check className="h-3.5 w-3.5" /> : <Copy className="h-3.5 w-3.5" />}
                  {copied ? 'Copied' : 'Copy'}
                </button>
              </div>
              {expiresAt && (
                <p className="text-xs text-gray-500">
                  Expires {new Date(expiresAt).toLocaleString()}
                </p>
              )}
            </div>
          ) : null}
        </div>

        <div className="flex items-center justify-end gap-2 border-t border-gray-200 px-4 py-3">
          <button
            onClick={onClose}
            className="rounded-md px-3 py-1.5 text-sm text-gray-700 hover:bg-gray-100"
          >
            Close
          </button>
          <button
            onClick={generate}
            disabled={generating}
            className="inline-flex items-center gap-1.5 rounded-md bg-blue-600 px-3 py-1.5 text-sm font-medium text-white hover:bg-blue-700 disabled:opacity-50"
          >
            {generating ? (
              <Loader2 className="h-4 w-4 animate-spin" />
            ) : (
              <Link2 className="h-4 w-4" />
            )}
            {previewUrl ? 'Generate new link' : 'Generate link'}
          </button>
        </div>
      </div>
    </div>
  )
}
