"use client";

import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { toPng } from "html-to-image";
import { Film, ImageIcon, ImagePlus, PlayCircle, Sparkles, Target, Trash2, Video } from "lucide-react";
import { ReviewShareStudio, dataUrlToFile } from "@/components/reviews/review-share-studio";
import {
  BackgroundPicker,
  BackgroundVideoLayer,
  MindavioLogo,
  MindavioLogoCompact,
  useBackgroundPicker,
} from "@/components/shared/background-picker";
import { captureElementWithVideoBackground } from "@/lib/review-video-export";
import { fmtDelta, fmtMs, type FocusReviewSnapshot } from "@/stores/focus-store";
import type { CalendarEvent, Task } from "@/types";
import type { ChatSharePayload } from "@/components/chat/share-to-chat-modal";

interface FocusReviewExportProps {
  events: CalendarEvent[];
  remainingTasks: Task[];
  review: FocusReviewSnapshot;
}

function formatSessionRange(review: FocusReviewSnapshot) {
  const start = review.startedAt ? new Date(review.startedAt) : new Date(review.endedAt);
  const end = new Date(review.endedAt);
  const date = end.toLocaleDateString("de-DE", {
    day: "2-digit",
    month: "short",
    year: "numeric",
  });
  const startTime = start.toLocaleTimeString("de-DE", {
    hour: "2-digit",
    minute: "2-digit",
  });
  const endTime = end.toLocaleTimeString("de-DE", {
    hour: "2-digit",
    minute: "2-digit",
  });
  return `${date} · ${startTime} - ${endTime}`;
}

function formatEventTime(iso: string) {
  return new Intl.DateTimeFormat("de-DE", {
    hour: "2-digit",
    minute: "2-digit",
  }).format(new Date(iso));
}

interface MediaAttachment {
  file: File;
  /** blob URL — for live <video> preview only (cannot be captured by html-to-image) */
  objectUrl: string;
  /** jpeg data URL captured via canvas — safe to embed inside cardRef for PNG export */
  exportDataUrl: string | null;
  type: "image" | "video";
}

/** Seek a video (via blob URL) to its first keyframe and capture a jpeg data URL poster. */
function capturePoster(objectUrl: string): Promise<string | null> {
  return new Promise((resolve) => {
    const video = document.createElement("video");
    video.muted = true;
    video.playsInline = true;
    video.preload = "metadata";
    video.src = objectUrl; // blob URL — instant, no memory copy
    const cleanup = () => { video.removeAttribute("src"); video.load(); };
    const capture = () => {
      try {
        const canvas = document.createElement("canvas");
        canvas.width = video.videoWidth || 1280;
        canvas.height = video.videoHeight || 720;
        const ctx = canvas.getContext("2d");
        if (!ctx) { cleanup(); resolve(null); return; }
        ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
        cleanup();
        resolve(canvas.toDataURL("image/jpeg", 0.82));
      } catch { cleanup(); resolve(null); }
    };
    video.addEventListener("loadeddata", () => {
      if (video.duration && Number.isFinite(video.duration)) {
        video.currentTime = Math.min(0.12, Math.max(video.duration - 0.05, 0));
      } else { capture(); }
    }, { once: true });
    video.addEventListener("seeked", capture, { once: true });
    video.addEventListener("error", () => { cleanup(); resolve(null); }, { once: true });
  });
}

/** Read an image file as a data URL for embedding in the export card. */
function readImageAsDataUrl(file: File): Promise<string> {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onload = (e) => resolve(e.target?.result as string);
    reader.onerror = reject;
    reader.readAsDataURL(file);
  });
}

export function FocusReviewExport({
  events,
  remainingTasks,
  review,
}: FocusReviewExportProps) {
  const cardRef = useRef<HTMLDivElement>(null);
  const mediaInputRef = useRef<HTMLInputElement>(null);
  const [media, setMedia] = useState<MediaAttachment | null>(null);
  const [mediaLoading, setMediaLoading] = useState(false);

  // Revoke blob URL when media changes or component unmounts to prevent memory leaks
  useEffect(() => {
    return () => {
      if (media?.objectUrl) URL.revokeObjectURL(media.objectUrl);
    };
  }, [media]);

  const handleMediaUpload = useCallback(async (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (!file) return;
    e.target.value = "";
    setMediaLoading(true);
    try {
      const objectUrl = URL.createObjectURL(file); // instant — no file reading
      const isVideo = file.type.startsWith("video/");
      // Start export-data capture (async) while preview is already live via objectUrl
      const exportDataUrl = isVideo
        ? await capturePoster(objectUrl).catch(() => null)
        : await readImageAsDataUrl(file).catch(() => null);
      setMedia({ file, objectUrl, exportDataUrl, type: isVideo ? "video" : "image" });
    } finally {
      setMediaLoading(false);
    }
  }, []);

  const bg = useBackgroundPicker("mb-dark");
  const isVideoExport = bg.isCustomVideo && !!bg.customVideo;

  const avgTaskTime = review.completedTasks.length
    ? review.workDuration / review.completedTasks.length
    : 0;
  const tasksPerHour = review.workDuration > 0
    ? (review.completedTasks.length / review.workDuration) * 3_600_000
    : 0;
  const longestTask = useMemo(
    () =>
      review.completedTasks.reduce<FocusReviewSnapshot["completedTasks"][number] | null>(
        (currentLongest, task) => {
          if (!currentLongest || task.delta > currentLongest.delta) return task;
          return currentLongest;
        },
        null,
      ),
    [review.completedTasks],
  );

  const sessionLabel = useMemo(() => formatSessionRange(review), [review]);
  const reviewMessage = useMemo(
    () => `Hier ist mein Focus Review für ${sessionLabel}.`,
    [sessionLabel],
  );

  const buildSharePayload = useCallback(async (): Promise<ChatSharePayload> => {
    if (!cardRef.current) {
      throw new Error("Die Focus-Review-Karte ist noch nicht bereit.");
    }

    const dateKey = new Date(review.endedAt).toISOString().split("T")[0];
    const files: File[] = [];

    if (isVideoExport && bg.customVideo) {
      files.push(
        await captureElementWithVideoBackground(cardRef.current, {
          durationMs: 6500,
          fileName: `Mindavio-Focus-Review-${dateKey}.webm`,
          fps: 30,
          pixelRatio: 2,
          videoSrc: bg.customVideo,
        }),
      );
    } else {
      const dataUrl = await toPng(cardRef.current, {
        pixelRatio: 3,
        cacheBust: true,
      });
      files.push(dataUrlToFile(dataUrl, `Mindavio-Focus-Review-${dateKey}.png`));
    }

    // Also attach the original media file so the recipient gets the full video/image
    if (media?.file) files.push(media.file);

    return {
      files,
      message: isVideoExport
        ? `Hier ist mein Focus Review als Video für ${sessionLabel}.`
        : reviewMessage,
    };
  }, [bg.customVideo, isVideoExport, media, review.endedAt, reviewMessage, sessionLabel]);

  const { accentColor, textColor, subtleColor, showLogo } = bg.theme;

  return (
    <ReviewShareStudio
      artifactType="focus"
      buildPayload={buildSharePayload}
      controls={
        <div className="flex flex-wrap gap-6">
          <BackgroundPicker
            presetId={bg.presetId}
            customImage={bg.customImage}
            customVideo={bg.customVideo}
            onSelectPreset={bg.setPresetId}
            onUpload={bg.handleUpload}
            onRemoveCustom={bg.removeCustom}
          />
          {/* ── Media attachment ── */}
          <div>
            <p className="text-xs text-muted-foreground mb-2">Session Media</p>
            <div className="flex items-center gap-2">
              {media ? (
                <div className="flex items-center gap-2 rounded-xl border border-white/[0.10] bg-white/[0.04] px-3 py-1.5">
                  {media.type === "video" ? (
                    <Film className="h-3.5 w-3.5 text-violet-400 shrink-0" />
                  ) : (
                    <ImageIcon className="h-3.5 w-3.5 text-violet-400 shrink-0" />
                  )}
                  <span className="text-[11px] text-white/60 max-w-[100px] truncate">
                    {media.file.name}
                  </span>
                  <button
                    onClick={() => setMedia(null)}
                    className="ml-1 text-white/30 hover:text-red-400 transition-colors"
                  >
                    <Trash2 className="h-3 w-3" />
                  </button>
                </div>
              ) : (
                <button
                  onClick={() => mediaInputRef.current?.click()}
                  disabled={mediaLoading}
                  className="flex items-center gap-1.5 rounded-xl border border-dashed border-white/[0.12] bg-white/[0.03] px-3 py-1.5 text-[11px] font-medium text-white/40 transition-all hover:border-white/[0.22] hover:text-white/65 disabled:opacity-40"
                >
                  {mediaLoading ? (
                    <span className="h-3.5 w-3.5 animate-spin rounded-full border border-white/20 border-t-white/60" />
                  ) : (
                    <>
                      <ImagePlus className="h-3.5 w-3.5" />
                      <Video className="h-3 w-3" />
                    </>
                  )}
                  {mediaLoading ? "Lädt…" : "Foto oder Video"}
                </button>
              )}
              <input
                ref={mediaInputRef}
                type="file"
                accept="image/*,video/*"
                className="hidden"
                onChange={handleMediaUpload}
              />
            </div>
          </div>
        </div>
      }
      defaultMessage={reviewMessage}
      description={isVideoExport ? "Teile deine Session als Video mit Hintergrund" : "Teile deine Session als Bild mit Hintergrund"}
      downloadLabel={isVideoExport ? "Als Video speichern" : "Als Bild speichern"}
      icon={isVideoExport ? <Video className="h-4 w-4 text-white" /> : <ImageIcon className="h-4 w-4 text-white" />}
      shareDescription={isVideoExport ? "Sende dein Focus-Review-Video direkt an einen Chat." : "Sende dein Focus-Review-Bild direkt an einen Chat."}
      shareTitle="Focus Review an Chat senden"
      title="Focus Review Export"
      tone="violet"
    >

      <div className="overflow-hidden rounded-[28px] border border-white/[0.08]">
        <div
          ref={cardRef}
          className="relative p-8"
          style={{
            ...bg.bgStyle,
            fontFamily:
              'Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
          }}
        >
          <BackgroundVideoLayer src={bg.isCustomVideo ? bg.customVideo : null} />

          {bg.isCustom && <div className="absolute inset-0 bg-black/35" />}

          <div
            className="pointer-events-none absolute inset-0 flex items-center justify-center"
            style={{ opacity: showLogo ? 0.55 : 0.35 }}
          >
            {!isVideoExport && <MindavioLogo size={340} />}
          </div>

          {!bg.isCustom && (
            <>
              <div
                className="absolute -right-12 -top-12 h-72 w-72 rounded-full opacity-15 blur-3xl"
                style={{ background: accentColor }}
              />
              <div
                className="absolute -bottom-16 -left-16 h-56 w-56 rounded-full opacity-10 blur-3xl"
                style={{ background: accentColor }}
              />
            </>
          )}

          <div className="relative mb-8 flex items-center justify-between">
            <div className="flex items-center gap-3">
              <MindavioLogoCompact size={28} />
              <span
                className="text-[15px] font-semibold tracking-[-0.01em]"
                style={{ color: textColor }}
              >
                Mindavio
              </span>
            </div>
            <span
              className="text-[11px] font-medium uppercase tracking-[0.12em]"
              style={{ color: subtleColor }}
            >
              Focus Review
            </span>
          </div>

          <div className="relative mb-6">
            <p className="text-xs font-medium" style={{ color: subtleColor }}>
              Session
            </p>
            <p className="mt-0.5 text-xs" style={{ color: subtleColor }}>
              {sessionLabel}
            </p>
          </div>

          <div className="relative mb-8">
            <p className="mb-1 text-xs font-medium" style={{ color: subtleColor }}>
              Abschluss
            </p>
            <div className="flex items-end gap-3">
              <p className="text-4xl font-bold tracking-tight" style={{ color: textColor }}>
                {review.completedTasks.length} Tasks
              </p>
              <span className="pb-1 text-sm font-medium" style={{ color: subtleColor }}>
                in {fmtMs(review.workDuration)}
              </span>
            </div>
          </div>

          <div className="relative grid grid-cols-4 gap-4">
            <ReviewStatCard
              accentColor={accentColor}
              label="Fokus"
              subtleColor={subtleColor}
              textColor={textColor}
              value={fmtDelta(review.focusDuration)}
            />
            <ReviewStatCard
              accentColor={accentColor}
              label="Arbeitszeit"
              subtleColor={subtleColor}
              textColor={textColor}
              value={fmtMs(review.workDuration)}
            />
            <ReviewStatCard
              accentColor={accentColor}
              label="Termine"
              subtleColor={subtleColor}
              textColor={textColor}
              value={String(events.length)}
            />
            <ReviewStatCard
              accentColor={accentColor}
              label="Offen"
              subtleColor={subtleColor}
              textColor={textColor}
              value={String(remainingTasks.length)}
            />
          </div>

          <div className="relative mt-6 grid grid-cols-[1.15fr_0.85fr] gap-5">
            <div
              className="rounded-2xl p-5"
              style={{
                background: `${accentColor}08`,
                boxShadow: `inset 0 0 0 1px ${accentColor}15`,
              }}
            >
              <div className="mb-3 flex items-center gap-2">
                <Target className="h-4 w-4" style={{ color: textColor }} />
                <p className="text-xs font-semibold uppercase tracking-[0.16em]" style={{ color: subtleColor }}>
                  Task Zeiten
                </p>
              </div>
              <div className="space-y-2.5">
                {review.completedTasks.slice(0, 4).map((task) => (
                  <div key={task.taskId} className="flex items-center justify-between gap-3">
                    <div className="min-w-0">
                      <p className="truncate text-sm font-medium" style={{ color: textColor }}>
                        {task.taskTitle}
                      </p>
                      <p className="text-[11px]" style={{ color: subtleColor }}>
                        Fertig um{" "}
                        {new Date(task.completedAt).toLocaleTimeString("de-DE", {
                          hour: "2-digit",
                          minute: "2-digit",
                        })}
                      </p>
                    </div>
                    <span className="shrink-0 text-sm font-semibold text-emerald-300">
                      {fmtDelta(task.delta)}
                    </span>
                  </div>
                ))}
                {review.completedTasks.length === 0 && (
                  <p className="text-sm" style={{ color: subtleColor }}>
                    Keine erledigten Tasks in dieser Session.
                  </p>
                )}
              </div>
            </div>

            <div className="space-y-4">
              <div
                className="rounded-2xl p-5"
                style={{
                  background: `${accentColor}08`,
                  boxShadow: `inset 0 0 0 1px ${accentColor}15`,
                }}
              >
                <div className="mb-2 flex items-center gap-2">
                  <Sparkles className="h-4 w-4" style={{ color: textColor }} />
                  <p className="text-xs font-semibold uppercase tracking-[0.16em]" style={{ color: subtleColor }}>
                    Wichtig
                  </p>
                </div>
                <div className="space-y-2">
                  <QuickInfo label="Ø pro Task" value={review.completedTasks.length ? fmtDelta(avgTaskTime) : "—"} />
                  <QuickInfo label="Tasks / Stunde" value={tasksPerHour > 0 ? tasksPerHour.toFixed(1) : "0.0"} />
                  <QuickInfo label="Längste Task" value={longestTask ? fmtDelta(longestTask.delta) : "—"} />
                </div>
              </div>

              <div
                className="rounded-2xl p-5"
                style={{
                  background: `${accentColor}08`,
                  boxShadow: `inset 0 0 0 1px ${accentColor}15`,
                }}
              >
                <div className="mb-2 flex items-center gap-2">
                  <Sparkles className="h-4 w-4" style={{ color: textColor }} />
                  <p className="text-xs font-semibold uppercase tracking-[0.16em]" style={{ color: subtleColor }}>
                    Termine
                  </p>
                </div>
                <div className="space-y-2">
                  {events.slice(0, 3).map((event) => (
                    <div key={event.id} className="flex items-center justify-between gap-3">
                      <p className="truncate text-sm font-medium" style={{ color: textColor }}>
                        {event.title}
                      </p>
                      <span className="shrink-0 text-[11px]" style={{ color: subtleColor }}>
                        {formatEventTime(event.start_time)}
                      </span>
                    </div>
                  ))}
                  {events.length === 0 && (
                    <p className="text-sm" style={{ color: subtleColor }}>
                      Keine Termine in dieser Session.
                    </p>
                  )}
                </div>
              </div>
            </div>
          </div>

          {/* ── Media attachment embedded in card (export-safe: data URLs only) ── */}
          {media?.exportDataUrl && (
            <div className="relative mt-6 overflow-hidden rounded-xl" style={{ boxShadow: `0 0 0 1px ${accentColor}15` }}>
              {media.type === "video" ? (
                <div className="relative">
                  {/* eslint-disable-next-line @next/next/no-img-element */}
                  <img
                    src={media.exportDataUrl}
                    alt="Video-Vorschau"
                    className="w-full rounded-xl object-cover max-h-48"
                  />
                  <div className="absolute inset-0 flex items-center justify-center">
                    <div className="flex h-10 w-10 items-center justify-center rounded-full bg-black/50 backdrop-blur-sm">
                      <PlayCircle className="h-6 w-6 text-white/80" />
                    </div>
                  </div>
                  <div
                    className="absolute bottom-2 right-2 flex items-center gap-1 rounded-full px-2 py-0.5 text-[9px] font-bold uppercase tracking-wider"
                    style={{ background: `${accentColor}25`, color: accentColor }}
                  >
                    <Film className="h-2.5 w-2.5" />
                    Video
                  </div>
                </div>
              ) : (
                // eslint-disable-next-line @next/next/no-img-element
                <img
                  src={media.exportDataUrl}
                  alt="Session Screenshot"
                  className="w-full rounded-xl object-cover max-h-64"
                />
              )}
            </div>
          )}
          {/* Placeholder shown in card when video poster is still loading */}
          {media?.type === "video" && !media.exportDataUrl && mediaLoading && (
            <div
              className="relative mt-6 flex h-32 w-full items-center justify-center overflow-hidden rounded-xl"
              style={{ boxShadow: `0 0 0 1px ${accentColor}15`, background: "rgba(0,0,0,0.25)" }}
            >
              <Video className="h-8 w-8 opacity-30" style={{ color: accentColor }} />
            </div>
          )}

          <div
            className="relative mt-6 flex items-center justify-between border-t pt-4"
            style={{ borderColor: `${accentColor}15` }}
          >
            <span className="text-[10px]" style={{ color: subtleColor }}>
              mindavio.app
            </span>
            <span className="text-[10px]" style={{ color: subtleColor }}>
              Generiert am{" "}
              {new Date(review.endedAt).toLocaleDateString("de-DE", {
                day: "2-digit",
                month: "short",
                year: "numeric",
              })}
            </span>
          </div>
        </div>
      </div>

      {/* ── Live video preview — rendered OUTSIDE cardRef so html-to-image skips it ── */}
      {media?.type === "video" && media.objectUrl && (
        <div className="mt-4 overflow-hidden rounded-2xl border border-white/[0.08]">
          <div className="mb-2 flex items-center gap-2 px-4 pt-3">
            <Film className="h-3.5 w-3.5 text-violet-400" />
            <p className="text-[11px] font-semibold uppercase tracking-[0.14em] text-white/35">
              Live-Vorschau · {media.file.name}
            </p>
          </div>
          <video
            src={media.objectUrl}
            controls
            className="w-full rounded-b-2xl"
            style={{ maxHeight: 260 }}
          />
        </div>
      )}
    </ReviewShareStudio>
  );
}

function ReviewStatCard({
  accentColor,
  label,
  subtleColor,
  textColor,
  value,
}: {
  accentColor: string;
  label: string;
  subtleColor: string;
  textColor: string;
  value: string;
}) {
  return (
    <div
      className="rounded-2xl p-4"
      style={{
        background: `${accentColor}08`,
        boxShadow: `inset 0 0 0 1px ${accentColor}15`,
      }}
    >
      <p className="text-[11px] font-medium" style={{ color: subtleColor }}>
        {label}
      </p>
      <p className="mt-2 text-xl font-bold" style={{ color: textColor }}>
        {value}
      </p>
    </div>
  );
}

function QuickInfo({ label, value }: { label: string; value: string }) {
  return (
    <div className="flex items-center justify-between gap-3 text-sm">
      <span className="text-white/45">{label}</span>
      <span className="font-semibold text-white">{value}</span>
    </div>
  );
}
