import { useEffect, useMemo, useState } from "react";
import { createPortal } from "react-dom";
import { listBlockedUsers, updateMyProfile } from "../api/users";
import type { AuthUser } from "../chat/types";
import { useAuthStore } from "../store/authStore";
import { AppPreferences, getAppPreferences, updateAppPreferences } from "../utils/preferences";

type SettingsPage = "main" | "general" | "notifications" | "privacy";

interface Props {
  open: boolean;
  onClose: () => void;
}

export function SettingsPanel({ open, onClose }: Props) {
  const me = useAuthStore((s) => s.me);
  const [page, setPage] = useState<SettingsPage>("main");
  const [prefs, setPrefs] = useState<AppPreferences>(() => getAppPreferences());
  const [blockedCount, setBlockedCount] = useState(0);
  const [savingPrivacy, setSavingPrivacy] = useState(false);
  const [allowPrivateMessages, setAllowPrivateMessages] = useState(true);
  const [profileDraft, setProfileDraft] = useState({
    name: "",
    username: "",
    bio: "",
    avatarUrl: "",
  });

  useEffect(() => {
    if (!me) {
      return;
    }
    setAllowPrivateMessages(me.allow_private_messages);
    setProfileDraft({
      name: me.name || "",
      username: me.username || "",
      bio: me.bio || "",
      avatarUrl: me.avatar_url || "",
    });
  }, [me]);

  useEffect(() => {
    if (!open) {
      return;
    }
    setPrefs(getAppPreferences());
  }, [open]);

  useEffect(() => {
    if (!open || page !== "privacy") {
      return;
    }
    let cancelled = false;
    void (async () => {
      try {
        const blocked = await listBlockedUsers();
        if (!cancelled) {
          setBlockedCount(blocked.length);
        }
      } catch {
        if (!cancelled) {
          setBlockedCount(0);
        }
      }
    })();
    return () => {
      cancelled = true;
    };
  }, [open, page]);

  const title = useMemo(() => {
    if (page === "general") return "General";
    if (page === "notifications") return "Notifications";
    if (page === "privacy") return "Privacy and Security";
    return "Settings";
  }, [page]);

  if (!open || !me) {
    return null;
  }

  function updatePrefs(patch: Partial<AppPreferences>) {
    setPrefs(updateAppPreferences(patch));
  }

  const notificationStatus = "Notification" in window ? Notification.permission : "denied";

  return createPortal(
    <div className="fixed inset-0 z-[150] bg-slate-950/60" onClick={onClose}>
      <aside
        className="absolute left-0 top-0 flex h-full w-full max-w-md flex-col border-r border-slate-700/70 bg-slate-900/95 shadow-2xl"
        onClick={(event) => event.stopPropagation()}
      >
        <div className="flex items-center justify-between border-b border-slate-700/60 px-4 py-3">
          <div className="flex items-center gap-2">
            {page !== "main" ? (
              <button className="rounded bg-slate-700 px-2 py-1 text-xs" onClick={() => setPage("main")} type="button">
                Back
              </button>
            ) : null}
            <p className="text-lg font-semibold">{title}</p>
          </div>
          <button className="rounded bg-slate-700 px-2 py-1 text-xs" onClick={onClose} type="button">
            Close
          </button>
        </div>

        <div className="tg-scrollbar min-h-0 flex-1 overflow-y-auto">
          {page === "main" ? (
            <>
              <section className="border-b border-slate-700/60 px-4 py-4">
                <p className="mb-2 text-xs uppercase tracking-wide text-slate-400">Profile</p>
                <div className="space-y-2">
                  <input
                    className="w-full rounded bg-slate-800 px-3 py-2 text-sm"
                    placeholder="Name"
                    value={profileDraft.name}
                    onChange={(e) => setProfileDraft((prev) => ({ ...prev, name: e.target.value }))}
                  />
                  <input
                    className="w-full rounded bg-slate-800 px-3 py-2 text-sm"
                    placeholder="Username"
                    value={profileDraft.username}
                    onChange={(e) => setProfileDraft((prev) => ({ ...prev, username: e.target.value.replace("@", "") }))}
                  />
                  <input
                    className="w-full rounded bg-slate-800 px-3 py-2 text-sm"
                    placeholder="Bio"
                    value={profileDraft.bio}
                    onChange={(e) => setProfileDraft((prev) => ({ ...prev, bio: e.target.value }))}
                  />
                  <input
                    className="w-full rounded bg-slate-800 px-3 py-2 text-sm"
                    placeholder="Avatar URL"
                    value={profileDraft.avatarUrl}
                    onChange={(e) => setProfileDraft((prev) => ({ ...prev, avatarUrl: e.target.value }))}
                  />
                  <button
                    className="w-full rounded bg-sky-500 px-3 py-2 text-sm font-semibold text-slate-950"
                    onClick={async () => {
                      const updated = await updateMyProfile({
                        name: profileDraft.name.trim() || undefined,
                        username: profileDraft.username.trim() || undefined,
                        bio: profileDraft.bio.trim() || null,
                        avatar_url: profileDraft.avatarUrl.trim() || null,
                      });
                      useAuthStore.setState({ me: updated as AuthUser });
                    }}
                    type="button"
                  >
                    Save profile
                  </button>
                </div>
              </section>

              <section className="border-b border-slate-700/60 py-1">
                <SettingsRow label="General Settings" value={`${prefs.messageFontSize}px, ${prefs.theme}`} onClick={() => setPage("general")} />
                <SettingsRow
                  label="Notifications"
                  value={prefs.webNotifications ? "Enabled" : "Disabled"}
                  onClick={() => setPage("notifications")}
                />
                <SettingsRow
                  label="Privacy and Security"
                  value={allowPrivateMessages ? "Everybody can message" : "Messages disabled"}
                  onClick={() => setPage("privacy")}
                />
              </section>
            </>
          ) : null}

          {page === "general" ? (
            <div className="space-y-4 px-4 py-3">
              <section className="rounded border border-slate-700/70 bg-slate-800/50 p-3">
                <p className="mb-2 text-xs uppercase tracking-wide text-slate-400">Settings</p>
                <p className="mb-2 text-sm">Message Font Size</p>
                <div className="flex items-center gap-3">
                  <input
                    className="w-full"
                    min={12}
                    max={24}
                    step={1}
                    type="range"
                    value={prefs.messageFontSize}
                    onChange={(e) => updatePrefs({ messageFontSize: Number(e.target.value) })}
                  />
                  <span className="text-sm">{prefs.messageFontSize}</span>
                </div>
              </section>

              <section className="rounded border border-slate-700/70 bg-slate-800/50 p-3">
                <p className="mb-2 text-xs uppercase tracking-wide text-slate-400">Theme</p>
                <RadioOption checked={prefs.theme === "light"} label="Light" onChange={() => updatePrefs({ theme: "light" })} />
                <RadioOption checked={prefs.theme === "dark"} label="Dark" onChange={() => updatePrefs({ theme: "dark" })} />
                <RadioOption checked={prefs.theme === "system"} label="System" onChange={() => updatePrefs({ theme: "system" })} />
              </section>

              <section className="rounded border border-slate-700/70 bg-slate-800/50 p-3">
                <p className="mb-2 text-xs uppercase tracking-wide text-slate-400">Keyboard</p>
                <RadioOption checked={prefs.sendMode === "enter"} label="Send with Enter (Shift+Enter new line)" onChange={() => updatePrefs({ sendMode: "enter" })} />
                <RadioOption checked={prefs.sendMode === "ctrl_enter"} label="Send with Ctrl+Enter (Enter new line)" onChange={() => updatePrefs({ sendMode: "ctrl_enter" })} />
              </section>
            </div>
          ) : null}

          {page === "notifications" ? (
            <div className="space-y-4 px-4 py-3">
              <section className="rounded border border-slate-700/70 bg-slate-800/50 p-3">
                <p className="mb-2 text-xs uppercase tracking-wide text-slate-400">Web Notifications</p>
                <CheckboxOption
                  checked={prefs.webNotifications}
                  label={`Web Notifications (${notificationStatus})`}
                  onChange={async (checked) => {
                    updatePrefs({ webNotifications: checked });
                    if (checked && "Notification" in window && Notification.permission === "default") {
                      await Notification.requestPermission();
                    }
                  }}
                />
                <CheckboxOption checked={prefs.messagePreview} label="Message Preview" onChange={(checked) => updatePrefs({ messagePreview: checked })} />
              </section>

              <section className="rounded border border-slate-700/70 bg-slate-800/50 p-3">
                <p className="mb-2 text-xs uppercase tracking-wide text-slate-400">Chats</p>
                <CheckboxOption checked={prefs.privateNotifications} label="Notifications for private chats" onChange={(checked) => updatePrefs({ privateNotifications: checked })} />
                <CheckboxOption checked={prefs.groupNotifications} label="Notifications for groups" onChange={(checked) => updatePrefs({ groupNotifications: checked })} />
                <CheckboxOption checked={prefs.channelNotifications} label="Notifications for channels" onChange={(checked) => updatePrefs({ channelNotifications: checked })} />
              </section>
            </div>
          ) : null}

          {page === "privacy" ? (
            <div className="space-y-4 px-4 py-3">
              <section className="rounded border border-slate-700/70 bg-slate-800/50 p-3">
                <p className="mb-2 text-xs uppercase tracking-wide text-slate-400">Privacy</p>
                <SettingsTextRow label="Blocked Users" value={String(blockedCount)} />
                <SettingsTextRow label="Who can see my profile photo?" value="Everybody" />
                <SettingsTextRow label="Who can see my last seen?" value="Everybody" />
                <SettingsTextRow label="Who can add me to groups?" value="Everybody" />
              </section>
              <section className="rounded border border-slate-700/70 bg-slate-800/50 p-3">
                <CheckboxOption
                  checked={allowPrivateMessages}
                  label="Who can send me messages? (Everybody)"
                  onChange={async (checked) => {
                    setAllowPrivateMessages(checked);
                    setSavingPrivacy(true);
                    try {
                      const updated = await updateMyProfile({ allow_private_messages: checked });
                      useAuthStore.setState({ me: updated as AuthUser });
                    } finally {
                      setSavingPrivacy(false);
                    }
                  }}
                  disabled={savingPrivacy}
                />
              </section>
            </div>
          ) : null}
        </div>
      </aside>
    </div>,
    document.body
  );
}

function SettingsRow({ label, value, onClick }: { label: string; value: string; onClick: () => void }) {
  return (
    <button className="flex w-full items-center justify-between px-4 py-3 text-left hover:bg-slate-800/60" onClick={onClick} type="button">
      <div className="min-w-0">
        <p className="truncate text-sm font-semibold">{label}</p>
        <p className="truncate text-xs text-slate-400">{value}</p>
      </div>
      <span className="text-slate-400">›</span>
    </button>
  );
}

function SettingsTextRow({ label, value }: { label: string; value: string }) {
  return (
    <div className="mb-2 flex items-center justify-between gap-2 rounded bg-slate-900/50 px-2 py-2">
      <p className="text-sm">{label}</p>
      <p className="text-xs text-slate-400">{value}</p>
    </div>
  );
}

function RadioOption({ checked, label, onChange }: { checked: boolean; label: string; onChange: () => void }) {
  return (
    <label className="mb-2 flex items-center gap-2 text-sm">
      <input checked={checked} onChange={onChange} type="radio" />
      <span>{label}</span>
    </label>
  );
}

function CheckboxOption({
  checked,
  label,
  onChange,
  disabled,
}: {
  checked: boolean;
  label: string;
  onChange: (checked: boolean) => void;
  disabled?: boolean;
}) {
  return (
    <label className="mb-2 flex items-center gap-2 text-sm">
      <input checked={checked} disabled={disabled} onChange={(e) => onChange(e.target.checked)} type="checkbox" />
      <span>{label}</span>
    </label>
  );
}

