import { useEffect, useRef, useState, Suspense } from "react";
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
} from "../components/ui/dialog";
import { api } from "../utils/api";
import { useAuthStore } from "../stores/authStore";
import { Loader, X } from "lucide-react";
import { LESSON_COMPONENT_MAP } from "./FetchLessonPage";
import type { LessonId } from "./FetchLessonPage";
import type { LessonDetails } from "../types/lesson";

interface LessonModalProps {
  lessonId: string | null;
  open: boolean;
  onOpenChange: (open: boolean) => void;
}

// UUIDs are video lessons; local lessons use readable keys like "ebrw-main-idea"
const UUID_REGEX =
  /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
const isVideoLesson = (id: string) => UUID_REGEX.test(id);

function getLocalLessonTitle(lessonId: string): string {
  const comp = LESSON_COMPONENT_MAP[lessonId as LessonId] as any;
  if (comp?.displayName) return comp.displayName;
  return lessonId
    .replace(/[-_]/g, " ")
    .replace(/\b\w/g, (c) => c.toUpperCase());
}

const STYLES = `
  @import url('https://fonts.googleapis.com/css2?family=Nunito:wght@400;700;800;900&family=Nunito+Sans:wght@400;600;700&display=swap');

  .lm-content {
    font-family: 'Nunito', sans-serif;
    background: #fffbf4;
    border: 2.5px solid #f3f4f6;
    border-radius: 28px !important;
    padding: 0;
    overflow: hidden;
    max-width: 680px;
    width: calc(100vw - 2rem);
    box-shadow: 0 20px 60px rgba(0,0,0,0.12);
    max-height: 90vh;
    display: flex;
    flex-direction: column;
  }

  @media (min-width: 1024px) {
    .lm-content {
      max-width: 1000px;
    }
  }
  .lm-dialog-header-hidden {
    position: absolute; width: 1px; height: 1px;
    padding: 0; margin: -1px; overflow: hidden;
    clip: rect(0,0,0,0); white-space: nowrap; border: 0;
  }
  .lm-header {
    display: flex; align-items: flex-start; justify-content: space-between;
    padding: 1.25rem 1.5rem 0; flex-shrink: 0; gap: 1rem;
  }
  .lm-title-wrap { display:flex; flex-direction:column; gap:0.2rem; flex:1; }
  .lm-eyebrow {
    font-size: 0.62rem; font-weight: 800; letter-spacing: 0.16em;
    text-transform: uppercase; color: #a855f7;
  }
  .lm-title {
    font-size: 1.2rem; font-weight: 900; color: #1e1b4b;
    letter-spacing: -0.01em; line-height: 1.25;
  }
  .lm-close-btn {
    width: 34px; height: 34px; flex-shrink: 0;
    border-radius: 50%; border: 2.5px solid #f3f4f6;
    background: white; cursor: pointer;
    display: flex; align-items: center; justify-content: center;
    box-shadow: 0 2px 8px rgba(0,0,0,0.06); transition: all 0.15s ease;
  }
  .lm-close-btn:hover { border-color: #fecdd3; background: #fff1f2; }
  .lm-body {
    overflow-y: auto; flex: 1;
    padding: 1rem 1.5rem 1.5rem;
    display: flex; flex-direction: column; gap: 1rem;
    -webkit-overflow-scrolling: touch;
  }
  .lm-video {
    width: 100%; border-radius: 18px;
    aspect-ratio: 16/9; background: #1e1b4b; display: block;
  }
  .lm-topic-chip {
    display: inline-flex; align-items: center; gap: 0.4rem;
    background: #f3e8ff; border: 2px solid #e9d5ff;
    border-radius: 100px; padding: 0.3rem 0.8rem;
    font-size: 0.7rem; font-weight: 800; letter-spacing: 0.08em;
    text-transform: uppercase; color: #9333ea; width: fit-content;
  }
  .lm-card {
    background: white; border: 2.5px solid #f3f4f6;
    border-radius: 18px; padding: 1rem 1.1rem;
    box-shadow: 0 3px 10px rgba(0,0,0,0.04);
  }
  .lm-card-label {
    font-size: 0.62rem; font-weight: 800; letter-spacing: 0.14em;
    text-transform: uppercase; color: #9ca3af; margin-bottom: 0.4rem;
  }
  .lm-card-text {
    font-family: 'Nunito Sans', sans-serif;
    font-size: 0.88rem; font-weight: 600; color: #374151; line-height: 1.6;
  }
  .lm-loading {
    display: flex; flex-direction: column; align-items: center;
    justify-content: center; gap: 0.75rem; padding: 3rem 1.5rem; flex: 1;
  }
  .lm-loading-spinner { animation: lmSpin 0.8s linear infinite; }
  @keyframes lmSpin { to { transform: rotate(360deg); } }
  .lm-loading-text { font-size: 0.85rem; font-weight: 700; color: #9ca3af; }
  .lm-error {
    display: flex; flex-direction: column; align-items: center;
    justify-content: center; gap: 0.5rem;
    padding: 3rem 1.5rem; text-align: center; flex: 1;
  }
  .lm-error-emoji { font-size: 2rem; }
  .lm-error-text { font-size: 0.85rem; font-weight: 700; color: #9ca3af; }

  /* Resources list */
  .lm-resources { display: flex; flex-direction: column; gap: 0.5rem; }
  .lm-resource-link {
    display: flex; align-items: center; gap: 0.6rem;
    padding: 0.6rem 0.8rem; border-radius: 12px;
    background: #f5f3ff; border: 1.5px solid #e9d5ff;
    color: #7c3aed; font-size: 0.8rem; font-weight: 700;
    text-decoration: none; transition: background 0.15s ease;
  }
  .lm-resource-link:hover { background: #ede9fe; }

  /* Creator badge */
  .lm-creator {
    display: flex; align-items: center; gap: 0.5rem;
    font-family: 'Nunito Sans', sans-serif;
    font-size: 0.75rem; font-weight: 600; color: #9ca3af;
  }
  .lm-creator-avatar {
    width: 24px; height: 24px; border-radius: 50%;
    background: linear-gradient(135deg, #a855f7, #3b82f6);
    display: flex; align-items: center; justify-content: center;
    font-size: 0.65rem; font-weight: 900; color: white; flex-shrink: 0;
  }
`;

const LoadingSpinner = () => (
  <div className="lm-loading">
    <Loader size={28} color="#a855f7" className="lm-loading-spinner" />
    <p className="lm-loading-text">Loading lesson...</p>
  </div>
);

export const LessonModal = ({
  lessonId,
  open,
  onOpenChange,
}: LessonModalProps) => {
  const user = useAuthStore((state) => state.user);

  const [loading, setLoading] = useState(false);
  const [lesson, setLesson] = useState<LessonDetails | null>(null);
  const [error, setError] = useState(false);
  const fetchingForId = useRef<string | null>(null);

  const LocalLessonComponent =
    lessonId && !isVideoLesson(lessonId)
      ? LESSON_COMPONENT_MAP[lessonId as LessonId]
      : null;

  const modalTitle = LocalLessonComponent
    ? getLocalLessonTitle(lessonId!)
    : loading
      ? "Loading..."
      : (lesson?.title ?? "Lesson");

  useEffect(() => {
    if (!open) {
      setLesson(null);
      setLoading(false);
      setError(false);
      fetchingForId.current = null;
      return;
    }

    if (!lessonId || !user || LocalLessonComponent) return;
    if (fetchingForId.current === lessonId) return;

    const fetchLesson = async () => {
      fetchingForId.current = lessonId;
      setLesson(null);
      setError(false);
      setLoading(true);

      try {
        const authStorage = localStorage.getItem("auth-storage");
        if (!authStorage) throw new Error("No auth storage");
        const {
          state: { token },
        } = JSON.parse(authStorage) as { state?: { token?: string } };
        if (!token) throw new Error("No token");

        // fetchLessonById returns LessonDetails directly
        const response: LessonDetails = await api.fetchLessonById(
          token,
          lessonId,
        );

        if (fetchingForId.current !== lessonId) return;
        setLesson(response);
      } catch (err) {
        console.error("Failed to fetch lesson", err);
        if (fetchingForId.current === lessonId) setError(true);
      } finally {
        if (fetchingForId.current === lessonId) setLoading(false);
      }
    };

    fetchLesson();
  }, [open, lessonId, user, LocalLessonComponent]);

  // topic on LessonDetails is Topic[] — use the first entry
  const topicName = Array.isArray(lesson?.topic)
    ? lesson.topic[0]?.name
    : ((lesson?.topic as any)?.name ?? null);

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <style>{STYLES}</style>
      <DialogContent className="lm-content" showCloseButton={false}>
        <DialogHeader className="lm-dialog-header-hidden">
          <DialogTitle>{modalTitle}</DialogTitle>
        </DialogHeader>

        <div className="lm-header">
          <div className="lm-title-wrap">
            <span className="lm-eyebrow">📖 Lesson</span>
            <h2 className="lm-title">{modalTitle}</h2>
          </div>
          <button className="lm-close-btn" onClick={() => onOpenChange(false)}>
            <X size={16} color="#6b7280" />
          </button>
        </div>

        {loading ? (
          <LoadingSpinner />
        ) : error ? (
          <div className="lm-error">
            <span className="lm-error-emoji">😕</span>
            <p className="lm-error-text">
              Couldn't load this lesson. Please try again.
            </p>
          </div>
        ) : (
          <div className="lm-body">
            {LocalLessonComponent ? (
              <Suspense fallback={<LoadingSpinner />}>
                <LocalLessonComponent />
              </Suspense>
            ) : (
              lesson && (
                <>
                  {/* Video */}
                  {lesson.video_url && (
                    <video
                      src={lesson.video_url}
                      controls
                      className="lm-video"
                    />
                  )}

                  {/* Topic chip */}
                  {topicName && (
                    <div>
                      <span className="lm-topic-chip">
                        <span
                          style={{
                            width: 6,
                            height: 6,
                            borderRadius: "50%",
                            background: "#a855f7",
                            flexShrink: 0,
                          }}
                        />
                        {topicName}
                      </span>
                    </div>
                  )}

                  {/* Description */}
                  {lesson.description && (
                    <div className="lm-card">
                      <p className="lm-card-label">About this lesson</p>
                      <p className="lm-card-text">{lesson.description}</p>
                    </div>
                  )}

                  {/* Content */}
                  {lesson.content && (
                    <div className="lm-card">
                      <p className="lm-card-label">Content</p>
                      <p className="lm-card-text">{lesson.content}</p>
                    </div>
                  )}

                  {/* Resources */}
                  {lesson.resources && lesson.resources.length > 0 && (
                    <div className="lm-card">
                      <p className="lm-card-label">Resources</p>
                      <div className="lm-resources">
                        {lesson.resources.map((r: any, i: number) => (
                          <a
                            key={i}
                            href={r.url ?? r.link ?? "#"}
                            target="_blank"
                            rel="noopener noreferrer"
                            className="lm-resource-link"
                          >
                            📎 {r.title ?? r.name ?? `Resource ${i + 1}`}
                          </a>
                        ))}
                      </div>
                    </div>
                  )}

                  {/* Created by */}
                  {lesson.created_by?.name && (
                    <div className="lm-creator">
                      <div className="lm-creator-avatar">
                        {lesson.created_by.name.charAt(0).toUpperCase()}
                      </div>
                      Lesson by {lesson.created_by.name}
                    </div>
                  )}
                </>
              )
            )}
          </div>
        )}
      </DialogContent>
    </Dialog>
  );
};
