import { useQuery, useMutation } from "@tanstack/react-query";
import { apiRequest, queryClient } from "@/lib/queryClient";
import type { Settings } from "@shared/schema";
import { useApp } from "@/lib/app-context";
import { ChevronRight, Download, FileAudio, HardDrive, Info, Moon, Share2, Sliders, Smartphone, Sun } from "lucide-react";
import { useEffect, useState } from "react";

const FORMATS = ["MP3", "WAV", "M4A"];
const QUALITIES = ["Niedrig", "Standard", "Hoch", "Studio"];
const STORAGES = ["Gerät", "iCloud", "Google Drive"];

export default function SettingsPage() {
  const { data: settings } = useQuery<Settings>({ queryKey: ["/api/settings"] });
  const { theme, setTheme } = useApp();
  const [openPicker, setOpenPicker] = useState<null | "format" | "quality" | "storage">(null);

  // PWA Install-Prompt (Android Chrome): wir hören auf das Event aus main.tsx.
  const [installable, setInstallable] = useState<boolean>(
    typeof window !== "undefined" && !!window.__tapecastInstallPrompt
  );
  const [installed, setInstalled] = useState<boolean>(
    typeof window !== "undefined" &&
      (window.matchMedia?.("(display-mode: standalone)").matches ||
        // @ts-expect-error – iOS Safari only
        window.navigator?.standalone === true)
  );
  useEffect(() => {
    const onInstallable = () => setInstallable(true);
    const onInstalled = () => {
      setInstallable(false);
      setInstalled(true);
    };
    window.addEventListener("tapecast:installable", onInstallable);
    window.addEventListener("tapecast:installed", onInstalled);
    return () => {
      window.removeEventListener("tapecast:installable", onInstallable);
      window.removeEventListener("tapecast:installed", onInstalled);
    };
  }, []);

  const triggerInstall = async () => {
    const ev = window.__tapecastInstallPrompt;
    if (!ev) return;
    try {
      await ev.prompt();
      const choice = await ev.userChoice;
      if (choice.outcome === "accepted") {
        setInstallable(false);
      }
    } finally {
      window.__tapecastInstallPrompt = null;
    }
  };

  const isIOS =
    typeof window !== "undefined" && /iPhone|iPad|iPod/i.test(window.navigator.userAgent);

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

  if (!settings) return null;

  const setField = (k: keyof Settings, v: string) => {
    updateMutation.mutate({ [k]: v } as Partial<Settings>);
  };

  const rows = [
    {
      key: "format",
      label: "Standard-Format",
      value: settings.format,
      icon: <FileAudio className="w-4 h-4" />,
      action: () => setOpenPicker("format"),
    },
    {
      key: "quality",
      label: "Qualität",
      value: settings.quality,
      icon: <Sliders className="w-4 h-4" />,
      action: () => setOpenPicker("quality"),
    },
    {
      key: "storage",
      label: "Speicherort",
      value: settings.storage,
      icon: <HardDrive className="w-4 h-4" />,
      action: () => setOpenPicker("storage"),
    },
  ];

  const pickerOptions =
    openPicker === "format" ? FORMATS : openPicker === "quality" ? QUALITIES : openPicker === "storage" ? STORAGES : [];
  const pickerTitle =
    openPicker === "format" ? "Standard-Format" : openPicker === "quality" ? "Qualität" : openPicker === "storage" ? "Speicherort" : "";

  return (
    <div className="flex flex-col h-full">
      <header className="px-5 pt-3 pb-3">
        <h1 className="text-lg font-semibold tracking-tight">Einstellungen</h1>
      </header>

      <div className="flex-1 overflow-y-auto px-4 pb-4 no-scrollbar">
        {/* Aufnahme-Gruppe */}
        <section className="mb-5">
          <h2 className="text-[11px] uppercase tracking-wider text-muted-foreground font-medium px-1 mb-2">Aufnahme</h2>
          <ul className="bg-card rounded-2xl border border-card-border divide-y divide-border overflow-hidden">
            {rows.map((r) => (
              <li key={r.key}>
                <button
                  onClick={r.action}
                  className="w-full flex items-center gap-3 px-4 py-3.5 hover-elevate active-elevate-2"
                  data-testid={`row-${r.key}`}
                >
                  <div className="w-8 h-8 rounded-lg bg-secondary flex items-center justify-center text-foreground/70">
                    {r.icon}
                  </div>
                  <span className="flex-1 text-left text-sm">{r.label}</span>
                  <span className="text-xs text-muted-foreground">{r.value}</span>
                  <ChevronRight className="w-4 h-4 text-muted-foreground" />
                </button>
              </li>
            ))}
          </ul>
        </section>

        {/* Erscheinungsbild */}
        <section className="mb-5">
          <h2 className="text-[11px] uppercase tracking-wider text-muted-foreground font-medium px-1 mb-2">Erscheinungsbild</h2>
          <div className="bg-card rounded-2xl border border-card-border overflow-hidden">
            <div className="flex items-center gap-3 px-4 py-3.5">
              <div className="w-8 h-8 rounded-lg bg-secondary flex items-center justify-center text-foreground/70">
                {theme === "dark" ? <Moon className="w-4 h-4" /> : <Sun className="w-4 h-4" />}
              </div>
              <span className="flex-1 text-sm">Modus</span>
              <div className="flex rounded-full bg-secondary p-1">
                {(["dark", "light"] as const).map((t) => (
                  <button
                    key={t}
                    onClick={() => {
                      setTheme(t);
                      setField("theme", t);
                    }}
                    className={`px-3 py-1 text-xs font-medium rounded-full transition ${
                      theme === t ? "bg-foreground text-background" : "text-foreground/70"
                    }`}
                    data-testid={`button-theme-${t}`}
                  >
                    {t === "dark" ? "Dunkel" : "Hell"}
                  </button>
                ))}
              </div>
            </div>
          </div>
        </section>

        {/* Installation */}
        {!installed && (
          <section className="mb-5">
            <h2 className="text-[11px] uppercase tracking-wider text-muted-foreground font-medium px-1 mb-2">
              Installation
            </h2>
            <div className="bg-card rounded-2xl border border-card-border overflow-hidden">
              {installable ? (
                <button
                  onClick={triggerInstall}
                  className="w-full flex items-center gap-3 px-4 py-3.5 hover-elevate active-elevate-2"
                  data-testid="button-install-pwa"
                >
                  <div className="w-8 h-8 rounded-lg bg-accent-red/15 flex items-center justify-center text-accent-red">
                    <Download className="w-4 h-4" />
                  </div>
                  <span className="flex-1 text-left text-sm font-medium">Als App installieren</span>
                  <span className="text-xs text-muted-foreground">Android</span>
                </button>
              ) : (
                <div className="px-4 py-3.5">
                  <div className="flex items-center gap-3">
                    <div className="w-8 h-8 rounded-lg bg-secondary flex items-center justify-center text-foreground/70">
                      {isIOS ? <Share2 className="w-4 h-4" /> : <Smartphone className="w-4 h-4" />}
                    </div>
                    <span className="flex-1 text-sm">Auf Startbildschirm</span>
                  </div>
                  <p className="text-[11px] text-muted-foreground mt-2 leading-relaxed">
                    {isIOS
                      ? "In Safari: Teilen-Icon \u2192 \u201eZum Home-Bildschirm\u201c. L\u00e4uft danach wie eine echte App."
                      : "Chrome zeigt das Installieren-Menu meist im 3-Punkte-Men\u00fc \u2192 \u201eApp installieren\u201c oder \u201eZum Startbildschirm\u201c."}
                  </p>
                </div>
              )}
            </div>
          </section>
        )}

        {/* About */}
        <section>
          <h2 className="text-[11px] uppercase tracking-wider text-muted-foreground font-medium px-1 mb-2">Über</h2>
          <div className="bg-card rounded-2xl border border-card-border overflow-hidden">
            <div className="flex items-center gap-3 px-4 py-3.5">
              <div className="w-8 h-8 rounded-lg bg-secondary flex items-center justify-center text-foreground/70">
                <Info className="w-4 h-4" />
              </div>
              <span className="flex-1 text-sm">Über die App</span>
              <span className="text-xs text-muted-foreground">Tapecast · v1.0 · Stufe 1</span>
            </div>
          </div>
          <p className="text-[11px] text-muted-foreground text-center mt-4 px-6">
            Echte Aufnahme · lokal gespeichert · Beats laufen parallel · Pitch &amp; Autotune folgen in Stufe 2.
          </p>
        </section>
      </div>

      {/* Picker sheet */}
      {openPicker && (
        <div className="fixed inset-0 z-40" data-testid="sheet-picker">
          <div className="absolute inset-0 bg-black/55 anim-fade" onClick={() => setOpenPicker(null)} />
          <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>
              <p className="text-center text-sm font-medium pb-2">{pickerTitle}</p>
              <ul className="px-3 pb-3">
                <div className="bg-card rounded-2xl divide-y divide-border overflow-hidden">
                  {pickerOptions.map((opt) => {
                    const active =
                      (openPicker === "format" && settings.format === opt) ||
                      (openPicker === "quality" && settings.quality === opt) ||
                      (openPicker === "storage" && settings.storage === opt);
                    return (
                      <li key={opt}>
                        <button
                          onClick={() => {
                            const field = openPicker as keyof Settings;
                            setField(field, opt);
                            setOpenPicker(null);
                          }}
                          className="w-full text-left px-4 py-3.5 text-sm flex items-center justify-between hover-elevate"
                          data-testid={`picker-option-${opt}`}
                        >
                          <span>{opt}</span>
                          {active && <span className="w-2 h-2 rounded-full bg-accent-red" />}
                        </button>
                      </li>
                    );
                  })}
                </div>
              </ul>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}
