import { useState } from "react";
import type { Recording } from "@shared/schema";
import { useApp, getRecordingBlob, getRecordingObjectUrl } from "@/lib/app-context";
import { Download, Share2, FileAudio, ExternalLink, X, Loader2 } from "lucide-react";
import { encodeToMp3 } from "@/lib/mp3-encoder";

export function ShareSheet({ recording, onClose }: { recording: Recording; onClose: () => void }) {
  const { showSnackbar } = useApp();
  const [encoding, setEncoding] = useState(false);

  const safeName = (recording.title || `tape-${recording.id}`).replace(/[^\w\-]+/g, "_");

  // Native Share — Web Share API Level 2 (files). Android Chrome / iOS Safari.
  const canShareFiles = typeof navigator !== "undefined" && typeof navigator.canShare === "function";

  const doNativeShareFile = async () => {
    try {
      const blob = await getRecordingBlob(recording);
      if (!blob) {
        showSnackbar({ message: "Audio nicht gefunden" });
        return;
      }
      const file = new File([blob], `${safeName}.${recording.fileExt}`, { type: recording.mimeType });
      if (navigator.canShare && navigator.canShare({ files: [file] })) {
        await navigator.share({ files: [file], title: recording.title, text: `Tapecast · ${recording.title}` });
        onClose();
      } else {
        // Fallback: Tab öffnen mit Object-URL.
        const url = await getRecordingObjectUrl(recording);
        if (url) window.open(url, "_blank");
        onClose();
      }
    } catch (e) {
      if ((e as Error).name !== "AbortError") {
        showSnackbar({ message: "Teilen fehlgeschlagen" });
      }
    }
  };

  const doDownloadOriginal = async () => {
    const blob = await getRecordingBlob(recording);
    if (!blob) {
      showSnackbar({ message: "Audio nicht gefunden" });
      return;
    }
    const url = URL.createObjectURL(blob);
    const a = document.createElement("a");
    a.href = url;
    a.download = `${safeName}.${recording.fileExt}`;
    document.body.appendChild(a);
    a.click();
    a.remove();
    setTimeout(() => URL.revokeObjectURL(url), 1500);
    showSnackbar({ message: `Download gestartet · ${recording.fileExt.toUpperCase()}` }, 2500);
    onClose();
  };

  const doDownloadMp3 = async () => {
    if (encoding) return;
    setEncoding(true);
    try {
      const blob = await getRecordingBlob(recording);
      if (!blob) {
        showSnackbar({ message: "Audio nicht gefunden" });
        return;
      }
      const arr = await blob.arrayBuffer();
      const mp3 = await encodeToMp3(arr);
      const mp3Blob = new Blob([mp3], { type: "audio/mpeg" });
      const url = URL.createObjectURL(mp3Blob);
      const a = document.createElement("a");
      a.href = url;
      a.download = `${safeName}.mp3`;
      document.body.appendChild(a);
      a.click();
      a.remove();
      setTimeout(() => URL.revokeObjectURL(url), 1500);
      showSnackbar({ message: "MP3 erstellt" }, 2500);
      onClose();
    } catch (e) {
      console.error(e);
      showSnackbar({ message: "MP3-Konvertierung fehlgeschlagen" });
    } finally {
      setEncoding(false);
    }
  };

  const doOpenInTab = async () => {
    const url = await getRecordingObjectUrl(recording);
    if (!url) {
      showSnackbar({ message: "Audio nicht gefunden" });
      return;
    }
    window.open(url, "_blank");
    onClose();
  };

  type Opt = { id: string; label: string; hint: string; icon: React.ReactNode; onClick: () => void; show?: boolean; loading?: boolean };

  const options: Opt[] = [
    {
      id: "native", label: "Teilen…", hint: "WhatsApp · Signal · Telegram · Mail",
      icon: <Share2 className="w-5 h-5" />, onClick: doNativeShareFile,
      show: canShareFiles,
    },
    {
      id: "original", label: `Download · ${recording.fileExt.toUpperCase()}`, hint: "Originaldatei, schnell",
      icon: <Download className="w-5 h-5" />, onClick: doDownloadOriginal,
    },
    {
      id: "mp3", label: "Download als MP3", hint: "Konvertiert im Browser · ~2 sec",
      icon: <FileAudio className="w-5 h-5" />, onClick: doDownloadMp3,
      loading: encoding,
    },
    {
      id: "open", label: "In neuem Tab öffnen", hint: "Player im Browser",
      icon: <ExternalLink className="w-5 h-5" />, onClick: doOpenInTab,
    },
  ].filter((o) => o.show !== false);

  return (
    <div className="fixed inset-0 z-40" data-testid="sheet-share">
      <div className="absolute inset-0 bg-black/55 anim-fade" onClick={onClose} />
      <div className="absolute left-0 right-0 bottom-0 anim-sheet">
        <div className="bg-popover text-popover-foreground rounded-t-3xl border-t border-border pb-safe">
          <div className="flex items-center justify-center pt-2 pb-1">
            <div className="w-9 h-1 rounded-full bg-muted-foreground/30" />
          </div>
          <div className="flex items-center justify-between px-5 pt-1 pb-3">
            <div className="min-w-0">
              <p className="text-xs text-muted-foreground">Teilen</p>
              <p className="text-sm font-medium truncate">{recording.title}</p>
            </div>
            <button
              onClick={onClose}
              className="w-9 h-9 rounded-full bg-secondary flex items-center justify-center"
              aria-label="Schließen"
              data-testid="button-close-share"
            >
              <X className="w-4 h-4" />
            </button>
          </div>
          <div className="px-3 pb-3">
            <ul className="divide-y divide-border bg-card rounded-2xl overflow-hidden">
              {options.map((o) => (
                <li key={o.id}>
                  <button
                    onClick={o.onClick}
                    disabled={o.loading}
                    className="w-full flex items-center gap-3 px-4 py-3.5 text-left hover-elevate active-elevate-2 disabled:opacity-60"
                    data-testid={`button-share-option-${o.id}`}
                  >
                    <div className="w-10 h-10 rounded-xl bg-secondary flex items-center justify-center text-foreground/80">
                      {o.loading ? <Loader2 className="w-5 h-5 animate-spin" /> : o.icon}
                    </div>
                    <div className="flex-1 min-w-0">
                      <p className="text-sm font-medium">{o.label}</p>
                      <p className="text-[11px] text-muted-foreground">{o.hint}</p>
                    </div>
                  </button>
                </li>
              ))}
            </ul>
          </div>
        </div>
      </div>
    </div>
  );
}
