"use client";

import { useState, useEffect } from "react";
import { AppShell } from "@/components/AppShell";
import { useAuth } from "@/components/AuthProvider";
import { useServiceWorker } from "@/components/ServiceWorkerProvider";
import { APP_NAME } from "@/lib/constants";
import { LogOut, Users, Bell, Sparkles, Loader2, Check, Key, ChevronDown } from "lucide-react";
import Link from "next/link";

interface UserSettings {
  reminderEnabled: boolean;
  reminderTime: string;
  reminderAlways: boolean;
  llmProvider: string | null;
  hasLlmKey: boolean;
  llmModel: string | null;
}

interface ModelInfo {
  id: string;
  name: string;
  description?: string;
}

const PROVIDERS = [
  { id: "openrouter", name: "OpenRouter", description: "Access many models, often cheapest" },
  { id: "openai", name: "OpenAI", description: "GPT-4o, GPT-4o-mini" },
  { id: "anthropic", name: "Anthropic", description: "Claude models" },
];

export default function SettingsPage() {
  const { user, logout } = useAuth();
  const { isSupported: swSupported, isRegistered: swRegistered, showNotification, subscribeToPush } = useServiceWorker();
  const [settings, setSettings] = useState<UserSettings | null>(null);
  const [isLoading, setIsLoading] = useState(true);
  const [isSaving, setIsSaving] = useState(false);
  const [showLlmSetup, setShowLlmSetup] = useState(false);
  const [notificationPermission, setNotificationPermission] = useState<NotificationPermission>("default");
  const [isPWA, setIsPWA] = useState(false);

  // LLM setup state
  const [selectedProvider, setSelectedProvider] = useState<string>("");
  const [apiKey, setApiKey] = useState("");
  const [models, setModels] = useState<ModelInfo[]>([]);
  const [selectedModel, setSelectedModel] = useState<string>("");
  const [isLoadingModels, setIsLoadingModels] = useState(false);
  const [modelError, setModelError] = useState<string | null>(null);

  useEffect(() => {
    async function loadSettings() {
      try {
        const res = await fetch("/api/settings");
        if (res.ok) {
          const data = await res.json();
          setSettings(data);
          if (data.llmProvider) {
            setSelectedProvider(data.llmProvider);
          }
          if (data.llmModel) {
            setSelectedModel(data.llmModel);
          }
        }
      } catch (error) {
        console.error("Failed to load settings:", error);
      } finally {
        setIsLoading(false);
      }
    }
    loadSettings();

    if ("Notification" in window) {
      setNotificationPermission(Notification.permission);
    }

    // Detect if running as PWA (standalone mode)
    const isStandalone = window.matchMedia("(display-mode: standalone)").matches ||
      (window.navigator as Navigator & { standalone?: boolean }).standalone === true;
    setIsPWA(isStandalone);
  }, []);

  // Ensure push subscription is active if permissions are granted
  useEffect(() => {
    if (notificationPermission === "granted" && swRegistered) {
      subscribeToPush().catch(console.error);
    }
  }, [notificationPermission, swRegistered, subscribeToPush]);

  const updateSetting = async (key: string, value: unknown) => {
    setIsSaving(true);
    try {
      const res = await fetch("/api/settings", {
        method: "PATCH",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ [key]: value }),
      });
      if (res.ok) {
        setSettings((prev) => prev ? { ...prev, [key]: value } : null);
      }
    } catch (error) {
      console.error("Failed to update setting:", error);
    } finally {
      setIsSaving(false);
    }
  };

  const requestNotificationPermission = async () => {
    if ("Notification" in window) {
      const permission = await Notification.requestPermission();
      setNotificationPermission(permission);
      if (permission === "granted") {
        updateSetting("reminderEnabled", true);
        const subscribed = await subscribeToPush();
        if (subscribed) {
          showNotification(APP_NAME, {
            body: "Notifications enabled! You will receive daily reminders.",
            icon: "/icons/icon.svg",
            tag: "welcome-notification",
          });
        }
      }
    }
  };

  const toggleReminder = async () => {
    if (!settings) return;

    if (!settings.reminderEnabled) {
      if (notificationPermission !== "granted") {
        await requestNotificationPermission();
      } else {
        updateSetting("reminderEnabled", true);
      }
    } else {
      updateSetting("reminderEnabled", false);
    }
  };

  const fetchModels = async () => {
    if (!selectedProvider || !apiKey) return;

    setIsLoadingModels(true);
    setModelError(null);
    setModels([]);

    try {
      const res = await fetch("/api/llm/models", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ provider: selectedProvider, apiKey }),
      });

      const data = await res.json();

      if (!res.ok) {
        setModelError(data.error || "Failed to fetch models");
        return;
      }

      setModels(data.models);
      if (data.models.length > 0) {
        setSelectedModel(data.models[0].id);
      }
    } catch {
      setModelError("Failed to connect to API");
    } finally {
      setIsLoadingModels(false);
    }
  };

  const saveLlmSettings = async () => {
    if (!selectedProvider || !apiKey || !selectedModel) return;

    setIsSaving(true);
    try {
      const res = await fetch("/api/settings", {
        method: "PATCH",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          llmProvider: selectedProvider,
          llmApiKey: apiKey,
          llmModel: selectedModel,
        }),
      });

      if (res.ok) {
        setSettings((prev) => prev ? {
          ...prev,
          llmProvider: selectedProvider,
          hasLlmKey: true,
          llmModel: selectedModel,
        } : null);
        setShowLlmSetup(false);
        setApiKey("");
      }
    } catch (error) {
      console.error("Failed to save LLM settings:", error);
    } finally {
      setIsSaving(false);
    }
  };

  const clearLlmSettings = async () => {
    setIsSaving(true);
    try {
      await fetch("/api/settings", {
        method: "PATCH",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          llmProvider: "",
          llmApiKey: "",
          llmModel: "",
        }),
      });
      setSettings((prev) => prev ? {
        ...prev,
        llmProvider: null,
        hasLlmKey: false,
        llmModel: null,
      } : null);
      setSelectedProvider("");
      setSelectedModel("");
      setModels([]);
    } catch (error) {
      console.error("Failed to clear LLM settings:", error);
    } finally {
      setIsSaving(false);
    }
  };

  // Reminder check interval - uses service worker for iOS compatibility
  useEffect(() => {
    if (!settings?.reminderEnabled || !settings?.reminderTime) return;

    // Track if we've shown the notification this minute
    let lastShownMinute = -1;

    const checkReminder = async () => {
      const now = new Date();
      const [hours, minutes] = settings.reminderTime.split(":").map(Number);
      const currentMinute = now.getHours() * 60 + now.getMinutes();

      if (now.getHours() === hours && now.getMinutes() === minutes && currentMinute !== lastShownMinute) {
        lastShownMinute = currentMinute;
        if (Notification.permission === "granted") {
          await showNotification(APP_NAME, {
            body: "Take a moment to reflect on what you're grateful for today.",
            icon: "/icons/icon.svg",
            tag: "daily-reminder",
          });
        }
      }
    };

    // Check immediately and then every minute
    checkReminder();
    const interval = setInterval(checkReminder, 60000);
    return () => clearInterval(interval);
  }, [settings?.reminderEnabled, settings?.reminderTime, showNotification]);

  const getProviderName = (id: string) => PROVIDERS.find(p => p.id === id)?.name || id;

  return (
    <AppShell>
      <header className="mb-8">
        <h1 className="text-2xl font-light">{APP_NAME}</h1>
        <p className="text-sm text-muted">Settings</p>
      </header>

      <div className="space-y-6">
        {/* Account info */}
        {user && (
          <div className="p-4 bg-surface border border-border rounded-xl">
            <h3 className="font-medium mb-1">Account</h3>
            <p className="text-sm text-muted">{user.email}</p>
            {user.name && <p className="text-sm text-muted">{user.name}</p>}
            <button
              onClick={logout}
              className="mt-3 flex items-center gap-2 text-sm text-red-400 hover:text-red-300"
            >
              <LogOut size={16} />
              Sign out
            </button>
          </div>
        )}

        {/* Admin */}
        {user?.isAdmin && (
          <Link
            href="/admin"
            className="p-4 bg-surface border border-border rounded-xl flex items-center gap-3 hover:border-muted transition-colors"
          >
            <Users size={20} className="text-accent" />
            <div>
              <h3 className="font-medium">User Management</h3>
              <p className="text-sm text-muted">Add users, reset passwords</p>
            </div>
          </Link>
        )}

        {/* Daily Reminder */}
        {!isLoading && settings && (
          <div className="p-4 bg-surface border border-border rounded-xl">
            <div className="flex items-center justify-between">
              <div className="flex items-center gap-3">
                <Bell size={20} className="text-accent" />
                <div>
                  <h3 className="font-medium">Daily reminder</h3>
                  <p className="text-sm text-muted">Get a gentle nudge to check in</p>
                </div>
              </div>
              <button
                onClick={toggleReminder}
                disabled={isSaving}
                className={`relative w-12 h-6 rounded-full transition-colors ${
                  settings.reminderEnabled ? "bg-accent" : "bg-border"
                }`}
              >
                <span
                  className={`absolute top-1 w-4 h-4 bg-white rounded-full transition-transform ${
                    settings.reminderEnabled ? "left-7" : "left-1"
                  }`}
                />
              </button>
            </div>
            {settings.reminderEnabled && (
              <div className="mt-4 space-y-4">
                <div className="flex items-center gap-3">
                  <label className="text-sm text-muted">Remind me at:</label>
                  <input
                    type="time"
                    value={settings.reminderTime}
                    onChange={(e) => updateSetting("reminderTime", e.target.value)}
                    className="px-3 py-1 bg-background border border-border rounded-lg text-sm focus:outline-none focus:border-muted"
                  />
                </div>
                <div className="flex items-center gap-3">
                  <input
                    type="checkbox"
                    id="reminderAlways"
                    checked={settings.reminderAlways}
                    onChange={(e) => updateSetting("reminderAlways", e.target.checked)}
                    className="w-4 h-4 rounded border-border text-accent focus:ring-accent"
                  />
                  <label htmlFor="reminderAlways" className="text-sm text-muted cursor-pointer">
                    Always remind me, even if I've already journaled today
                  </label>
                </div>
              </div>
            )}
            {settings.reminderEnabled && notificationPermission === "granted" && swRegistered && (
              <div className="mt-3 flex items-center justify-between">
                <div className="flex items-center gap-2 text-sm text-green-500">
                  <Check size={14} />
                  <span>Notifications ready{isPWA ? " (PWA mode)" : ""}</span>
                </div>
                <button
                  onClick={() => showNotification(APP_NAME, {
                    body: "Test notification - reminders are working!",
                    icon: "/icons/icon.svg",
                    tag: "test-notification",
                  })}
                  className="text-sm text-accent hover:underline"
                >
                  Test
                </button>
              </div>
            )}
            {settings.reminderEnabled && notificationPermission === "granted" && !swRegistered && (
              <p className="mt-2 text-sm text-amber-400">
                Service worker loading... Notifications may be limited.
              </p>
            )}
            {notificationPermission === "denied" && (
              <p className="mt-2 text-sm text-red-400">
                Notifications are blocked. Please enable them in your browser/device settings.
              </p>
            )}
            {settings.reminderEnabled && notificationPermission === "default" && (
              <p className="mt-2 text-sm text-amber-400">
                Notification permission not yet granted. Toggle reminders off and on to request permission.
              </p>
            )}
          </div>
        )}

        {/* AI Reflections */}
        {!isLoading && settings && (
          <div className="p-4 bg-surface border border-border rounded-xl">
            <div className="flex items-center justify-between">
              <div className="flex items-center gap-3">
                <Sparkles size={20} className="text-accent" />
                <div>
                  <h3 className="font-medium">AI reflections</h3>
                  <p className="text-sm text-muted">Generate insights from your entries</p>
                </div>
              </div>
              {settings.hasLlmKey ? (
                <Check size={20} className="text-green-500" />
              ) : (
                <button
                  onClick={() => setShowLlmSetup(true)}
                  className="px-3 py-1 text-sm bg-accent text-white rounded-lg hover:bg-accent/90"
                >
                  Set up
                </button>
              )}
            </div>

            {settings.hasLlmKey && !showLlmSetup && (
              <div className="mt-3 space-y-2">
                <p className="text-sm text-green-500">
                  {getProviderName(settings.llmProvider || "")} configured
                  {settings.llmModel && (
                    <span className="text-muted"> • {settings.llmModel}</span>
                  )}
                </p>
                <div className="flex items-center gap-3">
                  <button
                    onClick={() => setShowLlmSetup(true)}
                    className="text-sm text-muted hover:text-foreground"
                  >
                    Change
                  </button>
                  <button
                    onClick={clearLlmSettings}
                    className="text-sm text-red-400 hover:text-red-300"
                  >
                    Remove
                  </button>
                  <span className="text-muted">•</span>
                  <Link href="/reflections" className="text-sm text-accent hover:underline">
                    View reflections
                  </Link>
                </div>
              </div>
            )}

            {showLlmSetup && (
              <div className="mt-4 space-y-4 border-t border-border pt-4">
                {/* Provider selection */}
                <div>
                  <label className="block text-sm text-muted mb-2">Provider</label>
                  <div className="grid gap-2">
                    {PROVIDERS.map((provider) => (
                      <button
                        key={provider.id}
                        onClick={() => {
                          setSelectedProvider(provider.id);
                          setModels([]);
                          setSelectedModel("");
                          setModelError(null);
                        }}
                        className={`p-3 text-left rounded-lg border transition-colors ${
                          selectedProvider === provider.id
                            ? "border-accent bg-accent/10"
                            : "border-border hover:border-muted"
                        }`}
                      >
                        <p className="font-medium">{provider.name}</p>
                        <p className="text-sm text-muted">{provider.description}</p>
                      </button>
                    ))}
                  </div>
                </div>

                {/* API Key */}
                {selectedProvider && (
                  <div>
                    <label className="block text-sm text-muted mb-1">API Key</label>
                    <div className="flex gap-2">
                      <div className="relative flex-1">
                        <Key size={16} className="absolute left-3 top-1/2 -translate-y-1/2 text-muted" />
                        <input
                          type="password"
                          value={apiKey}
                          onChange={(e) => setApiKey(e.target.value)}
                          placeholder={
                            selectedProvider === "anthropic" ? "sk-ant-..." :
                            selectedProvider === "openai" ? "sk-..." :
                            "sk-or-..."
                          }
                          className="w-full pl-9 pr-3 py-2 bg-background border border-border rounded-lg text-sm focus:outline-none focus:border-muted"
                        />
                      </div>
                      <button
                        onClick={fetchModels}
                        disabled={!apiKey || isLoadingModels}
                        className="px-4 py-2 bg-accent text-white rounded-lg hover:bg-accent/90 disabled:opacity-50 flex items-center gap-2"
                      >
                        {isLoadingModels ? (
                          <Loader2 size={14} className="animate-spin" />
                        ) : null}
                        Load Models
                      </button>
                    </div>
                    <p className="mt-1 text-xs text-muted">
                      {selectedProvider === "anthropic" && (
                        <>Get your key from <a href="https://console.anthropic.com/settings/keys" target="_blank" rel="noopener noreferrer" className="text-accent hover:underline">console.anthropic.com</a></>
                      )}
                      {selectedProvider === "openai" && (
                        <>Get your key from <a href="https://platform.openai.com/api-keys" target="_blank" rel="noopener noreferrer" className="text-accent hover:underline">platform.openai.com</a></>
                      )}
                      {selectedProvider === "openrouter" && (
                        <>Get your key from <a href="https://openrouter.ai/keys" target="_blank" rel="noopener noreferrer" className="text-accent hover:underline">openrouter.ai</a></>
                      )}
                    </p>
                  </div>
                )}

                {/* Error */}
                {modelError && (
                  <p className="text-sm text-red-400">{modelError}</p>
                )}

                {/* Model selection */}
                {models.length > 0 && (
                  <div>
                    <label className="block text-sm text-muted mb-1">Model</label>
                    <div className="relative">
                      <select
                        value={selectedModel}
                        onChange={(e) => setSelectedModel(e.target.value)}
                        className="w-full px-3 py-2 bg-background border border-border rounded-lg text-sm focus:outline-none focus:border-muted appearance-none pr-10"
                      >
                        {models.map((model) => (
                          <option key={model.id} value={model.id}>
                            {model.name} {model.description && `- ${model.description}`}
                          </option>
                        ))}
                      </select>
                      <ChevronDown size={16} className="absolute right-3 top-1/2 -translate-y-1/2 text-muted pointer-events-none" />
                    </div>
                    <p className="mt-1 text-xs text-muted">
                      {selectedProvider === "openrouter" && "Sorted by price (cheapest first)"}
                      {selectedProvider === "openai" && "Mini models are cheapest"}
                      {selectedProvider === "anthropic" && "Haiku is cheapest, Opus is most capable"}
                    </p>
                  </div>
                )}

                {/* Actions */}
                <div className="flex gap-3 pt-2">
                  <button
                    onClick={() => {
                      setShowLlmSetup(false);
                      setApiKey("");
                      setModels([]);
                      setModelError(null);
                    }}
                    className="px-4 py-2 text-sm text-muted hover:text-foreground"
                  >
                    Cancel
                  </button>
                  {models.length > 0 && (
                    <button
                      onClick={saveLlmSettings}
                      disabled={isSaving || !selectedModel}
                      className="flex items-center gap-2 px-4 py-2 text-sm bg-accent text-white rounded-lg hover:bg-accent/90 disabled:opacity-50"
                    >
                      {isSaving && <Loader2 size={14} className="animate-spin" />}
                      Save
                    </button>
                  )}
                </div>
              </div>
            )}
          </div>
        )}

        <div className="pt-6 border-t border-border text-center text-sm text-muted">
          <p>{APP_NAME} v0.1.0</p>
          <p className="mt-1">A calm, private gratitude log.</p>
        </div>
      </div>
    </AppShell>
  );
}
