import React, { useMemo, useRef, useState } from "react";
import subtractHomeIcon from "./subtract-home.svg";
import { ReactPhotoSphereViewer } from "react-photo-sphere-viewer";
import { ReactMarkdownComponent } from "../../ReactMarkdown";
import { ThreeViewErrorBoundary } from "../../MediaViewer/ThreeViewErrorBoundary";
import {
  SightFrameThreeView,
  ThreeViewHandle,
} from "./SightFrameThreeView";
import { MinusIcon, PlusIcon } from "./SightFrameThreeViewIcons";
import "./SightFramePreview.css";

interface ArticleMedia {
  id: string;
  media_type: number;
  filename: string;
}

interface Article {
  id: number;
  heading: string;
  body: string;
  media: ArticleMedia[];
}

interface PreviewMediaData {
  id: string;
  media_type: number;
  filename?: string;
}

interface SightFramePreviewProps {
  sightName: string;
  previewMedia: PreviewMediaData | null;
  articles: Article[];
  onArticleSelect: (index: number) => void;
  previewFontSize?: number;
  selectedSection: number;
  onSectionChange: (section: number) => void;
}

// Matches SightFrame.jsx renderCurrentMedia — same structure, same CSS classes
function renderCurrentMedia(
  media: PreviewMediaData | ArticleMedia | null,
  token: string,
  threeViewResetKey: number,
  threeViewControlRef: React.MutableRefObject<ThreeViewHandle | null>,
  onZoomIn: () => void,
  onZoomOut: () => void,
  onThreeViewReset: () => void
) {
  if (!media) return null;

  const src = `${import.meta.env.VITE_KRBL_MEDIA}${media.id}/download?token=${token}`;
  const className = "sfp-sight-frame-media-item";

  switch (media.media_type) {
    // image (1), gif (3), sprite (4)
    case 1:
    case 3:
    case 4:
      return (
        <img
          src={src}
          alt=""
          className={className}
          onError={(e) => {
            (e.target as HTMLImageElement).style.display = "none";
          }}
        />
      );

    // video
    case 2:
      return (
        <video
          muted
          autoPlay
          loop
          playsInline
          className={className}
          onError={(e) => {
            (e.target as HTMLVideoElement).style.display = "none";
          }}
        >
          <source src={src} type="video/mp4" />
        </video>
      );

    // panorama
    case 5:
      return (
        <div
          className={`${className} panorama-container`}
          style={{ isolation: "isolate" }}
        >
          <ReactPhotoSphereViewer
            src={src}
            width={"100%"}
            height={"100%"}
          />
        </div>
      );

    // 3d
    case 6:
      return (
        <div className={className} style={{ position: "relative" }}>
          <ThreeViewErrorBoundary
            resetKey={`sfp-${media.id}-${threeViewResetKey}`}
            onReset={onThreeViewReset}
          >
            <SightFrameThreeView
              key={`sfp-3d-${media.id}-${threeViewResetKey}`}
              fileUrl={src}
              width={"100%"}
              height={"100%"}
              controlRef={threeViewControlRef}
            />
          </ThreeViewErrorBoundary>
          <div className="sfp-three-d-controls-bar">
            <button
              type="button"
              className="sfp-three-d-control-btn"
              title="Уменьшить"
              onPointerUp={onZoomOut}
            >
              <MinusIcon />
            </button>
            <button
              type="button"
              className="sfp-three-d-control-btn"
              title="Увеличить"
              onPointerUp={onZoomIn}
            >
              <PlusIcon />
            </button>
          </div>
        </div>
      );

    default:
      return (
        <div className={className}>
          <div className="sfp-sight-frame-media-placeholder">
            Неподдерживаемый тип медиа
          </div>
        </div>
      );
  }
}

export function SightFramePreview({
  sightName,
  previewMedia,
  articles,
  onArticleSelect,
  previewFontSize,
  selectedSection,
  onSectionChange,
}: SightFramePreviewProps) {
  const token = localStorage.getItem("token") ?? "";
  const [threeViewResetKey, setThreeViewResetKey] = useState(0);
  const threeViewControlRef = useRef<ThreeViewHandle | null>(null);

  const currentArticle =
    selectedSection >= 0 && selectedSection < articles.length
      ? articles[selectedSection]
      : null;

  const currentMedia: PreviewMediaData | ArticleMedia | null = currentArticle
    ? (currentArticle.media[0] ?? null)
    : previewMedia;

  const isCurrentMedia3D = currentMedia?.media_type === 6;

  // Replicates processedSightName from SightFrame.jsx
  const processedSightName = useMemo(() => {
    if (!sightName) return sightName;

    // Handle \n line breaks
    if (sightName.includes("\n")) {
      return sightName.split("\n").map((line, i) => (
        <React.Fragment key={i}>
          {i > 0 && <br />}
          {line}
        </React.Fragment>
      ));
    }

    const namePattern =
      /([А-Яа-яA-Za-z0-9]\. [А-Яа-яA-Za-z0-9]\. [А-Яа-яA-Za-z0-9]+)/g;
    const parts = sightName.split(namePattern);
    if (parts.length > 1) {
      return parts.map((part, index) => {
        const initialsPattern =
          /^[А-Яа-яA-Za-z0-9]\. [А-Яа-яA-Za-z0-9]\. [А-Яа-яA-Za-z0-9]+$/;
        if (initialsPattern.test(part)) {
          return (
            <span key={index}>
              <br />
              {part}
            </span>
          );
        }
        return <span key={index}>{part}</span>;
      });
    }
    return sightName;
  }, [sightName]);

  // Replicates titleLineHeight from SightFrame.jsx
  const titleLineHeight = useMemo(() => {
    if (!sightName) return "120%";
    const calculatedLineHeight = Math.max(
      100,
      Math.min(120, 120 - (sightName.replace(/\n/g, "").length / 10) * 1)
    );
    return `${calculatedLineHeight}%`;
  }, [sightName]);

  const isIntro = selectedSection === -1;

  return (
    <div className="sfp-sight-frame">
      {/* media stack — always rendered, matches .sight-frame-media-stack */}
      <div
        className={`sfp-sight-frame-media-stack${isCurrentMedia3D ? " three-d-view" : ""}`}
      >
        {currentMedia ? (
          renderCurrentMedia(
            currentMedia,
            token,
            threeViewResetKey,
            threeViewControlRef,
            () => threeViewControlRef.current?.zoomIn?.(),
            () => threeViewControlRef.current?.zoomOut?.(),
            () => setThreeViewResetKey((k) => k + 1)
          )
        ) : (
          <div className="sfp-sight-frame-media-placeholder">
            {isIntro ? "Медиа не добавлено" : "Нет медиа"}
          </div>
        )}
      </div>

      {/* content */}
      <div className="sfp-sight-frame-content">
        {/* title: intro-title (300px, 40px centered) or regular (24px with border) */}
        <div
          className={`sfp-sight-frame-title${isIntro ? " sfp-intro-title" : ""}`}
          style={{
            lineHeight: isIntro ? undefined : titleLineHeight,
            ...(isIntro && previewFontSize != null
              ? { fontSize: `${previewFontSize}px` }
              : {}),
          }}
        >
          <p
            style={{
              whiteSpace: "normal",
              wordBreak: "break-word",
              overflowWrap: "break-word",
            }}
          >
            {isIntro ? processedSightName : sightName}
          </p>
        </div>

        {/* text body — only for article sections */}
        {!isIntro && currentArticle && (
          <div className="sfp-sight-frame-text-wrapper">
            <div className="sfp-sight-frame-text">
              <ReactMarkdownComponent value={currentArticle.body} />
            </div>
          </div>
        )}
      </div>

      {/* menu — matches .sight-frame-menu */}
      <div className="sfp-sight-frame-menu">
        {/* back arrow — shown when not on intro */}
        {!isIntro && (
          <button
            className="sfp-back-btn"
            type="button"
            onClick={() => onSectionChange(-1)}
          >
            <img src={subtractHomeIcon} alt="" width="24" height="21" style={{ display: "block" }} />
          </button>
        )}

        {/* article nav buttons — matches .sight-frame-menu-point */}
        {articles.map((article, index) => (
          <button
            key={article.id}
            type="button"
            className={`sfp-sight-frame-menu-point${selectedSection === index ? " active" : ""}`}
            onClick={() => {
              onSectionChange(index);
              onArticleSelect(index);
            }}
          >
            {article.heading}
          </button>
        ))}
      </div>
    </div>
  );
}
