"use client";

import { useEffect, useRef, useState, type CSSProperties } from "react";
import { InlineContent, InlineText, useLandingEditor } from "@/components/cms/LandingInlineEditor";
import {
  LANDING_CAROUSEL_RATIOS,
  landingVideoEmbedUrl,
  parseLandingCarouselContent,
  type LandingCarouselContent,
  type LandingPageSection,
  type LandingPageType,
} from "@/lib/cms/landing-section-schema";

function LandingCountdown({ target }: { target: string }) {
  const [now, setNow] = useState<number | null>(null);
  const targetTime = Date.parse(target);

  useEffect(() => {
    const update = () => setNow(Date.now());
    update();
    const interval = window.setInterval(update, 1000);
    return () => window.clearInterval(interval);
  }, []);

  if (!Number.isFinite(targetTime)) return null;

  const remaining = now === null ? null : Math.max(0, targetTime - now);
  const days = remaining === null ? null : Math.floor(remaining / 86_400_000);
  const hours = remaining === null ? null : Math.floor((remaining % 86_400_000) / 3_600_000);
  const minutes = remaining === null ? null : Math.floor((remaining % 3_600_000) / 60_000);
  const seconds = remaining === null ? null : Math.floor((remaining % 60_000) / 1000);

  return (
    <time className="landing-countdown" dateTime={new Date(targetTime).toISOString()}>
      {remaining === null
        ? "Memuat hitung mundur…"
        : remaining === 0
          ? "Waktunya tiba"
          : `${days} hari · ${hours} jam · ${minutes} menit · ${seconds} detik`}
    </time>
  );
}

function blocks(value: string) {
  return value.split(/\r?\n\s*\r?\n/).map((item) => item.trim()).filter(Boolean);
}

function LandingCarousel({
  content,
  title,
  editing,
}: {
  content: LandingCarouselContent | null;
  title: string;
  editing: boolean;
}) {
  const [activeIndex, setActiveIndex] = useState(0);
  const slides = content?.slides.filter((slide) => slide.src.trim()) ?? [];

  if (!content || slides.length === 0) {
    return editing ? (
      <div className="landing-carousel-empty-preview">
        Tambahkan foto atau video melalui panel Susun section.
      </div>
    ) : null;
  }

  const selectedIndex = Math.min(activeIndex, slides.length - 1);
  const slide = slides[selectedIndex];
  const aspectRatio = LANDING_CAROUSEL_RATIOS.find((item) => item.value === content.ratio)?.css ?? "16 / 9";
  const embedUrl = slide.mediaType === "video" ? landingVideoEmbedUrl(slide.src) : null;

  return (
    <div className="landing-carousel">
      <div
        className="landing-carousel-media"
        style={{ aspectRatio }}
        role="group"
        aria-roledescription="slide"
        aria-label={`${selectedIndex + 1} dari ${slides.length}`}
      >
        {slide.mediaType === "image" ? (
          // eslint-disable-next-line @next/next/no-img-element
          <img src={slide.src} alt={slide.alt || title} loading="lazy" />
        ) : embedUrl ? (
          <iframe
            src={embedUrl}
            title={slide.caption || `${title} — video ${selectedIndex + 1}`}
            loading="lazy"
            allow="encrypted-media; picture-in-picture; fullscreen"
            allowFullScreen
            referrerPolicy="strict-origin-when-cross-origin"
            sandbox="allow-scripts allow-same-origin allow-presentation"
          />
        ) : (
          <video src={slide.src} controls playsInline preload="metadata">
            Video tidak dapat diputar di browser ini.
          </video>
        )}
      </div>
      {(slide.caption || slides.length > 1) && (
        <div className="landing-carousel-caption-row">
          <p>{slide.caption}</p>
          {slides.length > 1 && (
            <span>{String(selectedIndex + 1).padStart(2, "0")} / {String(slides.length).padStart(2, "0")}</span>
          )}
        </div>
      )}
      {slides.length > 1 && (
        <div className="landing-carousel-controls" aria-label="Navigasi carousel">
          <div className="landing-carousel-arrow-group">
            <button
              type="button"
              aria-label="Media sebelumnya"
              onClick={() => setActiveIndex((selectedIndex - 1 + slides.length) % slides.length)}
            >←</button>
            <button
              type="button"
              aria-label="Media berikutnya"
              onClick={() => setActiveIndex((selectedIndex + 1) % slides.length)}
            >→</button>
          </div>
          <div className="landing-carousel-dots">
            {slides.map((item, index) => (
              <button
                type="button"
                key={item.id}
                aria-label={`Tampilkan media ${index + 1}`}
                aria-current={selectedIndex === index ? "true" : undefined}
                onClick={() => setActiveIndex(index)}
              />
            ))}
          </div>
        </div>
      )}
    </div>
  );
}

export default function LandingSectionCanvas({
  pageType,
  pageKey,
  initialSections,
}: {
  pageType: LandingPageType;
  pageKey: string;
  initialSections: LandingPageSection[];
}) {
  const editor = useLandingEditor();
  const scope = `${pageType}:${pageKey}`;
  const sections = editor?.editing && editor.data?.pageSectionsScope === scope
    ? editor.data.pageSections
    : initialSections;
  const visibleSections = sections.filter((section) => section.enabled);
  const canvasRef = useRef<HTMLDivElement>(null);

  if (visibleSections.length === 0) return null;

  function moveSection(sectionId: string, targetId: string, column: number) {
    if (!editor || editor.data?.pageSectionsScope !== scope) return;
    const current = [...editor.data.pageSections];
    const sourceIndex = current.findIndex((section) => section.id === sectionId);
    const targetIndex = current.findIndex((section) => section.id === targetId);
    if (sourceIndex < 0 || targetIndex < 0) return;
    const [source] = current.splice(sourceIndex, 1);
    const insertionIndex = sectionId === targetId
      ? sourceIndex
      : targetIndex - Number(sourceIndex < targetIndex);
    current.splice(insertionIndex, 0, {
      ...source,
      layout: {
        column,
        columnSpan: source.layout?.columnSpan ?? 12,
        rowSpan: source.layout?.rowSpan ?? 1,
      },
    });
    editor.setPageSections(current);
  }

  return (
    <div
      ref={canvasRef}
      className={`landing-section-canvas landing-section-canvas-${pageType}${editor?.editing && editor.data?.pageSectionsScope === scope ? " is-editing" : ""}`}
    >
      <style jsx global>{`
        .landing-section-canvas { color: inherit; }
        .landing-section-canvas {
          display: grid;
          width: min(1080px, calc(100% - 40px));
          grid-template-columns: repeat(12, minmax(0, 1fr));
          grid-auto-rows: minmax(2.5rem, auto);
          gap: 0 12px;
          margin: 0 auto;
        }
        .landing-section-canvas > section {
          width: auto;
          min-width: 0;
          grid-column: 1 / -1;
          margin: 0;
          padding: clamp(42px, 7vw, 76px) 0;
          border-bottom: 1px solid rgba(148,163,184,.18);
        }
        .landing-section-canvas > section[data-landing-section] { position: relative; }
        .landing-section-canvas.is-editing {
          background-image: repeating-linear-gradient(
            to right,
            transparent 0,
            transparent calc(8.333333% - 1px),
            rgba(56,189,248,.18) calc(8.333333% - 1px),
            rgba(56,189,248,.18) 8.333333%
          );
          outline: 1px dashed rgba(56,189,248,.45);
          outline-offset: 4px;
        }
        .landing-section-canvas.is-editing > section[data-landing-section] {
          grid-column: var(--landing-column, 1) / span var(--landing-column-span, 12);
          grid-row: span var(--landing-row-span, 1);
        }
        .landing-section-drag-handle {
          position: absolute;
          z-index: 2;
          top: 8px;
          left: 0;
          display: inline-flex;
          min-height: 30px;
          align-items: center;
          gap: 5px;
          padding: 4px 9px;
          border: 1px solid #38bdf8;
          border-radius: 7px;
          background: #0b1220;
          color: #f8fafc;
          font: 700 11px/1.2 "DM Sans", "Segoe UI", sans-serif;
          cursor: grab;
        }
        .landing-section-drag-handle:active { cursor: grabbing; }
        .landing-section-drag-handle:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }
        .landing-section-canvas h2 {
          margin: 0 0 18px;
          font: 700 clamp(26px, 4vw, 42px)/1.15 "Space Grotesk", "DM Sans", sans-serif;
          letter-spacing: -.035em;
        }
        .landing-section-canvas p {
          margin: 0 0 12px;
          font-size: 15px;
          line-height: 1.8;
          white-space: pre-wrap;
        }
        .landing-section-canvas ul {
          display: grid;
          gap: 12px;
          margin: 0;
          padding-left: 22px;
          line-height: 1.75;
        }
        .landing-section-canvas details {
          padding: 16px 0;
          border-bottom: 1px solid rgba(148,163,184,.25);
        }
        .landing-section-canvas summary { cursor: pointer; font-weight: 750; }
        .landing-section-canvas summary:focus-visible { outline: 2px solid currentColor; outline-offset: 4px; }
        .landing-section-canvas blockquote {
          margin: 0;
          padding: 18px 20px;
          border-left: 3px solid currentColor;
          background: rgba(148,163,184,.08);
          white-space: pre-wrap;
        }
        .landing-section-canvas blockquote + blockquote { margin-top: 12px; }
        .landing-section-canvas figure { margin: 0; }
        .landing-section-canvas figure img {
          display: block;
          width: 100%;
          height: 220px;
          object-fit: cover;
          border-radius: 14px;
        }
        .landing-countdown {
          display: inline-block;
          padding: 14px 18px;
          border: 1px solid rgba(148,163,184,.3);
          border-radius: 10px;
          font-size: clamp(18px, 3vw, 26px);
          font-weight: 750;
          font-variant-numeric: tabular-nums;
        }
        .landing-section-dropdown select {
          width: min(100%, 420px);
          min-height: 46px;
          padding: 10px 12px;
          border: 1px solid rgba(148,163,184,.45);
          border-radius: 8px;
          background: transparent;
          color: inherit;
          font: inherit;
        }
        .landing-section-dropdown select:focus-visible {
          outline: 2px solid currentColor;
          outline-offset: 3px;
        }
        .landing-section-canvas .sr-only {
          position: absolute;
          width: 1px;
          height: 1px;
          overflow: hidden;
          clip: rect(0, 0, 0, 0);
          white-space: nowrap;
          clip-path: inset(50%);
        }
        .landing-section-gallery {
          display: grid;
          grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
          gap: 12px;
        }
        .landing-carousel {
          width: min(100%, 900px);
          margin: 0 auto;
        }
        .landing-carousel-media {
          overflow: hidden;
          border: 1px solid rgba(148,163,184,.25);
          border-radius: 16px;
          background: #07111b;
        }
        .landing-carousel-media img,
        .landing-carousel-media video,
        .landing-carousel-media iframe {
          display: block;
          width: 100%;
          height: 100%;
          border: 0;
          object-fit: contain;
        }
        .landing-carousel-caption-row {
          display: flex;
          align-items: center;
          justify-content: space-between;
          gap: 16px;
          padding: 10px 2px 0;
        }
        .landing-carousel-caption-row p {
          margin: 0;
          font-size: 13px;
        }
        .landing-carousel-caption-row span {
          flex: 0 0 auto;
          color: rgba(148,163,184,.8);
          font-size: 11px;
          font-variant-numeric: tabular-nums;
        }
        .landing-carousel-controls {
          display: flex;
          align-items: center;
          justify-content: space-between;
          gap: 16px;
          margin-top: 14px;
        }
        .landing-carousel-arrow-group,
        .landing-carousel-dots {
          display: flex;
          align-items: center;
          gap: 8px;
        }
        .landing-carousel-arrow-group button {
          display: grid;
          width: 40px;
          height: 40px;
          place-items: center;
          border: 1px solid rgba(148,163,184,.32);
          border-radius: 50%;
          background: transparent;
          color: inherit;
          font-size: 18px;
          cursor: pointer;
        }
        .landing-carousel-arrow-group button:hover { border-color: currentColor; }
        .landing-carousel-arrow-group button:focus-visible,
        .landing-carousel-dots button:focus-visible {
          outline: 2px solid currentColor;
          outline-offset: 3px;
        }
        .landing-carousel-dots button {
          width: 8px;
          height: 8px;
          padding: 0;
          border: 0;
          border-radius: 50%;
          background: rgba(148,163,184,.55);
          cursor: pointer;
        }
        .landing-carousel-dots button[aria-current="true"] {
          width: 24px;
          border-radius: 999px;
          background: #00bfff;
        }
        .landing-carousel-empty-preview {
          display: grid;
          min-height: 150px;
          place-items: center;
          padding: 24px;
          border: 1px dashed rgba(148,163,184,.45);
          border-radius: 14px;
          color: rgba(148,163,184,.85);
          text-align: center;
        }
        .landing-section-cta {
          padding: clamp(24px, 5vw, 48px);
          border: 1px solid rgba(56,189,248,.28);
          border-radius: 20px;
          background: rgba(56,189,248,.08);
        }
        .landing-section-cta a {
          display: inline-flex;
          min-height: 44px;
          align-items: center;
          margin-top: 10px;
          padding: 10px 16px;
          border-radius: 999px;
          background: #38bdf8;
          color: #07111b;
          font-size: 13px;
          font-weight: 800;
          text-decoration: none;
        }
        .landing-section-canvas-volunteer {
          background: #fff;
          color: #163a3a;
        }
        .landing-section-canvas-volunteer > section { border-color: #dce8e4; }
        .landing-section-canvas-volunteer .landing-section-cta { background: #eff8f4; border-color: #cde6d8; }
        .landing-section-canvas-volunteer .landing-section-cta a { background: #087f83; color: white; }
        .landing-section-canvas-event {
          color: #f1f5f9;
        }
        @media (max-width: 600px) {
          .landing-section-canvas { width: calc(100% - 28px); }
          .landing-section-canvas.is-editing > section[data-landing-section] {
            grid-column: 1 / -1;
          }
          .landing-section-canvas-gallery { grid-template-columns: 1fr; }
        }
      `}</style>
      {visibleSections.map((section) => {
        const path = `landingSections.${section.id}` as const;
        const paragraphs = section.content.trim() ? blocks(section.content) : [];
        const lines = section.content.split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
        const carouselContent = section.type === "carousel"
          ? parseLandingCarouselContent(section.content)
          : null;
        const countdownValid = Number.isFinite(Date.parse(section.content));
        if (section.type === "countdown" && !countdownValid && !editor?.editing) return null;
        if (
          section.type === "carousel" &&
          !editor?.editing &&
          (!carouselContent || carouselContent.slides.every((slide) => !slide.src.trim()))
        ) return null;
        const ctaHref = pageType === "event"
          ? "#registrasi"
          : pageType === "volunteer"
            ? "#volunteer-form"
            : "/kegiatan";

        return (
          <section
            key={section.id}
            className={section.type === "cta" ? "landing-section-cta" : undefined}
            aria-labelledby={section.title ? `landing-section-${section.id}` : undefined}
            aria-label={!section.title ? section.type : undefined}
            data-landing-section={editor?.editing ? section.id : undefined}
            style={{
              "--landing-column": section.layout?.column ?? 1,
              "--landing-column-span": section.layout?.columnSpan ?? 12,
              "--landing-row-span": section.layout?.rowSpan ?? 1,
            } as CSSProperties}
            onDragOver={editor?.editing ? (event) => event.preventDefault() : undefined}
            onDrop={editor?.editing ? (event) => {
              event.preventDefault();
              const draggedId = event.dataTransfer.getData("text/landing-section");
              if (!draggedId || !canvasRef.current) return;
              const bounds = canvasRef.current.getBoundingClientRect();
              const fraction = Math.max(0, Math.min(0.999, (event.clientX - bounds.left) / bounds.width));
              const dragged = sections.find((item) => item.id === draggedId);
              const span = dragged?.layout?.columnSpan ?? 12;
              moveSection(draggedId, section.id, Math.min(13 - span, Math.floor(fraction * 12) + 1));
            } : undefined}
          >
            {editor?.editing && (
              <button
                type="button"
                className="landing-section-drag-handle"
                draggable
                aria-label={`Geser section ${section.title || section.type} pada canvas`}
                onDragStart={(event) => {
                  event.dataTransfer.setData("text/landing-section", section.id);
                  event.dataTransfer.effectAllowed = "move";
                }}
              >
                <span aria-hidden="true">⠿</span> Geser
              </button>
            )}
            {section.title && (
              <InlineText
                as="h2"
                id={`landing-section-${section.id}`}
                path={`${path}.title`}
                value={section.title}
              />
            )}
            {section.type === "carousel" ? (
              <LandingCarousel
                content={carouselContent}
                title={section.title}
                editing={Boolean(editor?.editing)}
              />
            ) : section.type === "countdown" ? (
              countdownValid ? (
                <LandingCountdown target={section.content} />
              ) : (
                <p>Atur tanggal dan waktu target di panel Susunan.</p>
              )
            ) : (
              <InlineContent
                path={`${path}.content`}
                value={section.content}
                label={section.title || "section"}
              >
                {section.type === "dropdown" ? (
                  lines.length > 0 ? (
                    <label className="landing-section-dropdown">
                      <span className="sr-only">{section.title || "Pilih salah satu"}</span>
                      <select aria-label={section.title || "Pilih salah satu"} defaultValue="">
                        <option value="">Pilih...</option>
                        {lines.slice(0, 100).map((option, index) => (
                          <option key={`${section.id}-${index}`} value={option}>{option}</option>
                        ))}
                      </select>
                    </label>
                  ) : null
                ) : section.type === "faq" ? (
                  paragraphs.map((item, index) => {
                    const [question, ...answer] = item.split(/\r?\n/);
                    if (!question || answer.length === 0) return <p key={index}>{item}</p>;
                    return (
                      <details key={`${section.id}-${index}`}>
                        <summary>{question.replace(/^Q:\s*/i, "")}</summary>
                        <p>{answer.join(" ").replace(/^A:\s*/i, "")}</p>
                      </details>
                    );
                  })
                ) : section.type === "gallery" ? (
                  <div className="landing-section-gallery">
                    {lines.map((src, index) => (
                      <figure key={`${section.id}-${index}`}>
                        {/* CMS gallery sources are restricted to HTTPS URLs or root-relative paths by the API. */}
                        {/* eslint-disable-next-line @next/next/no-img-element */}
                        <img src={src} width="600" height="380" loading="lazy" alt={`${section.title || "Galeri"} ${index + 1}`} />
                      </figure>
                    ))}
                  </div>
                ) : section.type === "testimonials" ? (
                  paragraphs.map((item, index) => <blockquote key={`${section.id}-${index}`}>{item}</blockquote>)
                ) : ["benefits", "steps", "schedule", "speakers"].includes(section.type) ? (
                  lines.length > 0 && (
                    <ul>
                      {lines.map((line, index) => <li key={`${section.id}-${index}`}>{line}</li>)}
                    </ul>
                  )
                ) : (
                  paragraphs.map((item, index) => (
                    <p key={`${section.id}-${index}`}>{item}</p>
                  ))
                )}
              </InlineContent>
            )}
            {section.type === "cta" && (
              <a href={ctaHref}>
                {pageType === "event" ? "Lihat pendaftaran" : pageType === "volunteer" ? "Gabung sebagai volunteer" : "Jelajahi kegiatan"}
                <span aria-hidden="true"> →</span>
              </a>
            )}
          </section>
        );
      })}
    </div>
  );
}
