"use client";

import * as React from "react";
import {
  AlertTriangle,
  ExternalLink,
  Loader2,
  Pencil,
  RefreshCw,
} from "lucide-react";

import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import type { ViewConfig } from "@/lib/hooks/use-view-data";
import { cn } from "@/lib/utils";

/** Allowed schemes for embed src; rejects javascript:, data:, etc. */
export function sanitizeEmbedUrl(raw: string): string | null {
  const trimmed = raw.trim();
  if (!trimmed) return null;
  let parsed: URL;
  try {
    parsed = new URL(trimmed);
  } catch {
    return null;
  }
  if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
    return null;
  }
  // href is serialized safely for iframe src (no HTML/script injection)
  return parsed.href;
}

const EXAMPLE_SERVICES = [
  "Figma",
  "Google Docs",
  "Miro",
  "Loom",
  "YouTube",
] as const;

export interface EmbedViewProps {
  config: ViewConfig & { embedUrl?: string };
  className?: string;
}

export function EmbedView({ config, className }: EmbedViewProps) {
  const [sessionUrl, setSessionUrl] = React.useState<string | null>(null);
  const [draft, setDraft] = React.useState("");
  const [validationError, setValidationError] = React.useState<string | null>(
    null,
  );

  const effectiveUrl = config.embedUrl ?? sessionUrl;

  React.useEffect(() => {
    if (config.embedUrl) {
      setDraft(config.embedUrl);
    }
  }, [config.embedUrl]);

  const handlePreview = () => {
    setValidationError(null);
    const safe = sanitizeEmbedUrl(draft);
    if (!safe) {
      setValidationError(
        "Enter a valid URL starting with http:// or https://",
      );
      return;
    }
    setSessionUrl(safe);
  };

  const handleChangeUrl = () => {
    setSessionUrl(null);
    setDraft(effectiveUrl ?? "");
    setValidationError(null);
  };

  if (!effectiveUrl) {
    return (
      <div
        className={cn(
          "flex min-h-[320px] flex-1 flex-col items-center justify-center gap-6 p-8",
          className,
        )}
      >
        <div className="w-full max-w-md space-y-4 text-center">
          <div className="space-y-1">
            <h2 className="text-lg font-semibold tracking-tight">
              Embed a page
            </h2>
            <p className="text-sm text-muted-foreground">
              Paste a link to show it inside this view. Works best with tools
              that allow embedding.
            </p>
          </div>
          <div className="flex flex-col gap-2 sm:flex-row sm:items-stretch">
            <Input
              type="url"
              inputMode="url"
              autoComplete="url"
              placeholder="Paste a URL to embed..."
              value={draft}
              onChange={(e) => {
                setDraft(e.target.value);
                setValidationError(null);
              }}
              onKeyDown={(e) => {
                if (e.key === "Enter") handlePreview();
              }}
              className="text-left"
              aria-invalid={!!validationError}
            />
            <Button type="button" className="shrink-0 sm:w-auto" onClick={handlePreview}>
              Preview
            </Button>
          </div>
          {validationError ? (
            <p className="text-left text-sm text-destructive" role="alert">
              {validationError}
            </p>
          ) : null}
          <div className="space-y-2">
            <p className="text-xs font-medium text-muted-foreground">
              Often works well with
            </p>
            <div className="flex flex-wrap justify-center gap-1.5">
              {EXAMPLE_SERVICES.map((label) => (
                <Badge key={label} variant="outline" className="font-normal">
                  {label}
                </Badge>
              ))}
            </div>
          </div>
          <div
            className="flex items-start gap-2 rounded-md border border-amber-500/30 bg-amber-500/5 px-3 py-2 text-left text-xs text-muted-foreground"
            role="note"
          >
            <AlertTriangle
              className="mt-0.5 size-3.5 shrink-0 text-amber-600 dark:text-amber-500"
              aria-hidden
            />
            <span>
              Many sites block embedding in iframes for security. If you see a
              blank page or an error, the site may not allow this view—use{" "}
              <span className="font-medium text-foreground">Open in new tab</span>{" "}
              after loading.
            </span>
          </div>
        </div>
      </div>
    );
  }

  return (
    <EmbedFrame
      key={effectiveUrl}
      url={effectiveUrl}
      onChangeUrl={handleChangeUrl}
      className={className}
    />
  );
}

interface EmbedFrameProps {
  url: string;
  onChangeUrl: () => void;
  className?: string;
}

function EmbedFrame({ url, onChangeUrl, className }: EmbedFrameProps) {
  const [loadState, setLoadState] = React.useState<
    "loading" | "loaded" | "error"
  >("loading");
  const [reloadToken, setReloadToken] = React.useState(0);

  const safeUrl = sanitizeEmbedUrl(url);
  const iframeSrc = safeUrl ?? "";

  React.useEffect(() => {
    if (!safeUrl) {
      setLoadState("error");
      return;
    }
    setLoadState("loading");
  }, [safeUrl, reloadToken]);

  const handleRefresh = () => {
    setLoadState("loading");
    setReloadToken((x) => x + 1);
  };

  const displayUrl = safeUrl ?? url;
  const truncated =
    displayUrl.length > 64 ? `${displayUrl.slice(0, 61)}…` : displayUrl;

  return (
    <div
      className={cn(
        "flex min-h-0 flex-1 flex-col overflow-hidden rounded-md border border-border bg-background",
        className,
      )}
    >
      <div
        className="flex h-10 shrink-0 items-center gap-2 border-b border-border bg-muted/30 px-2"
        role="toolbar"
        aria-label="Embed controls"
      >
        <span
          className="min-w-0 flex-1 truncate px-1 text-xs text-muted-foreground"
          title={displayUrl}
        >
          {truncated}
        </span>
        <div className="flex shrink-0 items-center gap-0.5">
          <Button
            type="button"
            variant="ghost"
            size="sm"
            className="h-8 px-2"
            onClick={handleRefresh}
            disabled={!safeUrl}
            aria-label="Refresh embed"
          >
            <RefreshCw className="size-4" />
          </Button>
          <Button
            type="button"
            variant="ghost"
            size="sm"
            className="h-8 px-2"
            asChild
          >
            <a
              href={safeUrl || "#"}
              target="_blank"
              rel="noopener noreferrer"
              aria-label="Open in new tab"
            >
              <ExternalLink className="size-4" />
            </a>
          </Button>
          <Button
            type="button"
            variant="ghost"
            size="sm"
            className="h-8 px-2"
            onClick={onChangeUrl}
            aria-label="Change URL"
          >
            <Pencil className="size-4" />
          </Button>
        </div>
      </div>
      <div className="relative min-h-0 flex-1 bg-muted/20">
        {!safeUrl ? (
          <div className="flex h-full min-h-[200px] items-center justify-center p-6 text-center text-sm text-destructive">
            Invalid or unsupported URL. Use Change URL to enter an http(s)
            link.
          </div>
        ) : (
          <>
            {loadState === "loading" ? (
              <div
                className="absolute inset-0 z-10 flex items-center justify-center bg-background/80 backdrop-blur-[1px]"
                aria-live="polite"
                aria-busy="true"
              >
                <Loader2 className="size-8 animate-spin text-primary" aria-hidden />
                <span className="sr-only">Loading embed</span>
              </div>
            ) : null}
            {loadState === "error" ? (
              <div className="absolute inset-0 z-10 flex flex-col items-center justify-center gap-3 bg-background p-6 text-center">
                <p className="text-sm font-medium text-destructive">
                  Could not load this page in the embed.
                </p>
                <p className="max-w-sm text-xs text-muted-foreground">
                  The URL may be invalid, blocked, or the site may forbid
                  framing. Try opening in a new tab or a different URL.
                </p>
                <div className="flex flex-wrap justify-center gap-2">
                  <Button type="button" size="sm" onClick={handleRefresh}>
                    Try again
                  </Button>
                  <Button type="button" size="sm" variant="outline" asChild>
                    <a href={safeUrl} target="_blank" rel="noopener noreferrer">
                      Open in new tab
                    </a>
                  </Button>
                </div>
              </div>
            ) : null}
            {loadState !== "error" ? (
              <iframe
                key={`${iframeSrc}-${reloadToken}`}
                title="Embedded content"
                src={iframeSrc}
                className="size-full min-h-[400px] border-0"
                referrerPolicy="no-referrer-when-downgrade"
                onLoad={() => setLoadState("loaded")}
                onError={() => setLoadState("error")}
              />
            ) : null}
          </>
        )}
      </div>
    </div>
  );
}
