import { useState, useEffect, useMemo } from "react";
import { useQuery, useMutation } from "@tanstack/react-query";
import { apiRequest, queryClient } from "@/lib/queryClient";
import type { Recording } from "@shared/schema";
import { useApp } from "@/lib/app-context";
import { useLocation, useRoute } from "wouter";
import { Waveform } from "@/components/Waveform";
import { ArrowLeft, Pause, Play, RotateCcw, RotateCw, Share2, Scissors, Star, Check, X, Bookmark } from "lucide-react";
import { formatDurationHHMMSS } from "@/lib/format";
import { ShareSheet } from "@/components/ShareSheet";

export default function DetailPage() {
  const [, params] = useRoute<{ id: string }>("/aufnahme/:id");
  const [, navigate] = useLocation();
  const id = params ? Number(params.id) : 0;
  const { player, openPlayer, togglePlay, seekPlayer, showSnackbar } = useApp();

  const { data: rec, isLoading } = useQuery<Recording>({
    queryKey: ["/api/recordings", id],
    enabled: id > 0,
  });

  const [editingTitle, setEditingTitle] = useState(false);
  const [titleDraft, setTitleDraft] = useState("");
  const [trimMode, setTrimMode] = useState(false);
  const [trim, setTrim] = useState<{ start: number; end: number }>({ start: 0, end: 1 });
  const [shareOpen, setShareOpen] = useState(false);

  const updateMutation = useMutation({
    mutationFn: async (patch: Partial<Recording>) => {
      const res = await apiRequest("PATCH", `/api/recordings/${id}`, patch);
      return (await res.json()) as Recording;
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["/api/recordings"] });
      queryClient.invalidateQueries({ queryKey: ["/api/recordings", id] });
    },
  });

  // Open in player on first load.
  useEffect(() => {
    if (rec && (!player.recording || player.recording.id !== rec.id)) {
      openPlayer(rec, false);
    }
  }, [rec, player.recording, openPlayer]);

  const waveformBars = useMemo<number[]>(() => {
    if (!rec) return [];
    try { return JSON.parse(rec.waveform); } catch { return []; }
  }, [rec]);

  const markers = useMemo<number[]>(() => {
    if (!rec) return [];
    try { return JSON.parse(rec.markers); } catch { return []; }
  }, [rec]);

  if (isLoading || !rec) {
    return (
      <div className="flex items-center justify-center h-full">
        <p className="text-muted-foreground text-sm">Lade…</p>
      </div>
    );
  }

  const isCurrent = player.recording?.id === rec.id;
  const position = isCurrent ? player.position : 0;
  const progress = position / Math.max(1, rec.durationSec);
  const markerRatios = markers.map((m) => m / Math.max(1, rec.durationSec));

  const handleSeekRatio = (ratio: number) => {
    if (!isCurrent) openPlayer(rec, false);
    seekPlayer(ratio * rec.durationSec);
  };

  const handleSkip = (delta: number) => {
    if (!isCurrent) openPlayer(rec, false);
    seekPlayer(position + delta);
  };

  const startTitleEdit = () => {
    setTitleDraft(rec.title);
    setEditingTitle(true);
  };

  const saveTitle = () => {
    const next = titleDraft.trim();
    if (next && next !== rec.title) {
      updateMutation.mutate({ title: next });
    }
    setEditingTitle(false);
  };

  const toggleStar = () => {
    updateMutation.mutate({ starred: rec.starred === 1 ? 0 : 1 });
  };

  const enterTrim = () => {
    setTrim({ start: 0, end: 1 });
    setTrimMode(true);
  };

  const applyTrim = () => {
    const newDur = Math.max(1, Math.round((trim.end - trim.start) * rec.durationSec));
    updateMutation.mutate({ durationSec: newDur });
    setTrimMode(false);
    showSnackbar({ message: "Markierung gespeichert · Audio-Trim kommt in Stufe 2" }, 3500);
  };

  return (
    <div className="flex flex-col h-full">
      <header className="px-4 pt-3 pb-2 flex items-center gap-2">
        <button
          onClick={() => navigate("/bibliothek")}
          className="tap-target w-11 h-11 -ml-2 flex items-center justify-center rounded-full hover-elevate"
          aria-label="Zurück"
          data-testid="button-back"
        >
          <ArrowLeft className="w-5 h-5" />
        </button>
        <div className="flex-1 min-w-0">
          <p className="text-[11px] uppercase tracking-wider text-muted-foreground">Aufnahme</p>
          {editingTitle ? (
            <div className="flex items-center gap-1">
              <input
                autoFocus
                value={titleDraft}
                onChange={(e) => setTitleDraft(e.target.value)}
                onBlur={saveTitle}
                onKeyDown={(e) => {
                  if (e.key === "Enter") saveTitle();
                  if (e.key === "Escape") setEditingTitle(false);
                }}
                className="text-base font-semibold bg-transparent outline-none border-b border-primary w-full"
                data-testid="input-title"
              />
            </div>
          ) : (
            <button
              onClick={startTitleEdit}
              className="text-base font-semibold truncate text-left w-full"
              data-testid="button-edit-title"
            >
              {rec.title}
            </button>
          )}
        </div>
        <button
          onClick={toggleStar}
          className="tap-target w-11 h-11 flex items-center justify-center rounded-full hover-elevate"
          aria-label="Markieren"
          data-testid="button-star"
        >
          <Star className={`w-5 h-5 ${rec.starred === 1 ? "text-amber-400 fill-amber-400" : "text-muted-foreground"}`} />
        </button>
      </header>

      <div className="flex-1 overflow-y-auto px-4 pb-6 no-scrollbar">
        {/* Big waveform */}
        <div className="rounded-2xl bg-card border border-card-border p-4 mt-2">
          <Waveform
            bars={waveformBars}
            progress={trimMode ? 0 : progress}
            markers={trimMode ? [] : markerRatios}
            height={160}
            interactive={!trimMode}
            onSeek={handleSeekRatio}
            trim={trimMode ? trim : undefined}
            onTrimChange={trimMode ? setTrim : undefined}
          />
          <div className="flex justify-between mt-3 text-xs font-mono tabular-nums text-muted-foreground">
            <span data-testid="text-position">{formatDurationHHMMSS(Math.floor(position))}</span>
            <span data-testid="text-duration">{formatDurationHHMMSS(rec.durationSec)}</span>
          </div>
        </div>

        {/* Trim mode confirm bar */}
        {trimMode && (
          <div className="mt-4 flex items-center gap-3 rounded-2xl bg-secondary p-3">
            <p className="flex-1 text-xs text-muted-foreground">
              Ziehe die gelben Griffe, um die Aufnahme zuzuschneiden
            </p>
            <button
              onClick={() => setTrimMode(false)}
              className="w-10 h-10 rounded-full bg-card flex items-center justify-center"
              aria-label="Abbrechen"
              data-testid="button-trim-cancel"
            >
              <X className="w-4 h-4" />
            </button>
            <button
              onClick={applyTrim}
              className="w-10 h-10 rounded-full bg-accent-red flex items-center justify-center"
              aria-label="Übernehmen"
              data-testid="button-trim-apply"
            >
              <Check className="w-4 h-4 text-white" />
            </button>
          </div>
        )}

        {/* Transport controls */}
        {!trimMode && (
          <>
            <div className="mt-8 flex items-center justify-center gap-6">
              <button
                onClick={() => handleSkip(-10)}
                className="tap-target w-14 h-14 rounded-full bg-secondary flex items-center justify-center hover-elevate active:scale-95 transition"
                data-testid="button-skip-back"
                aria-label="10 Sekunden zurück"
              >
                <RotateCcw className="w-5 h-5" />
              </button>
              <button
                onClick={() => {
                  if (!isCurrent) openPlayer(rec, true);
                  else togglePlay();
                }}
                className="w-[72px] h-[72px] rounded-full bg-accent-red flex items-center justify-center shadow-lg active:scale-95 transition"
                style={{ boxShadow: "0 8px 28px rgba(255,59,48,0.35)" }}
                data-testid="button-play-detail"
                aria-label={isCurrent && player.playing ? "Pausieren" : "Abspielen"}
              >
                {isCurrent && player.playing ? (
                  <Pause className="w-7 h-7 text-white" fill="white" />
                ) : (
                  <Play className="w-7 h-7 text-white ml-1" fill="white" />
                )}
              </button>
              <button
                onClick={() => handleSkip(10)}
                className="tap-target w-14 h-14 rounded-full bg-secondary flex items-center justify-center hover-elevate active:scale-95 transition"
                data-testid="button-skip-forward"
                aria-label="10 Sekunden vor"
              >
                <RotateCw className="w-5 h-5" />
              </button>
            </div>

            {/* Action row */}
            <div className="mt-6 grid grid-cols-3 gap-3">
              <button
                onClick={enterTrim}
                className="rounded-2xl bg-card border border-card-border p-3 flex flex-col items-center gap-1 hover-elevate active-elevate-2"
                data-testid="button-trim-enter"
              >
                <Scissors className="w-5 h-5 text-foreground/80" />
                <span className="text-[11px] font-medium">Trim</span>
              </button>
              <button
                onClick={() => setShareOpen(true)}
                className="rounded-2xl bg-card border border-card-border p-3 flex flex-col items-center gap-1 hover-elevate active-elevate-2"
                data-testid="button-share-open"
              >
                <Share2 className="w-5 h-5 text-foreground/80" />
                <span className="text-[11px] font-medium">Teilen</span>
              </button>
              <button
                onClick={() => showSnackbar({ message: `${markers.length} Marker im Clip` }, 2500)}
                className="rounded-2xl bg-card border border-card-border p-3 flex flex-col items-center gap-1 hover-elevate active-elevate-2"
                data-testid="button-markers"
              >
                <Bookmark className="w-5 h-5 text-foreground/80" />
                <span className="text-[11px] font-medium">{markers.length} Marker</span>
              </button>
            </div>
          </>
        )}
      </div>

      {shareOpen && <ShareSheet recording={rec} onClose={() => setShareOpen(false)} />}
    </div>
  );
}
