"use client";

import { fetchOnce } from "@/lib/fetch-once";
import { words, type ConnectionMode, type ConnectionWords } from "@/lib/connection-mode";

import { createContext, useContext, useEffect, useState } from "react";

type Site = {
  siteName: string;
  tagline: string;
  /** Friends or followers, chosen by the admin. See lib/connection-mode. */
  connectionMode?: ConnectionMode;
  /** Undefined until the settings arrive, so nothing flashes offline. */
  siteOnline?: boolean;
  shutdownMessage?: string;
  /** Whether visitors can read without signing in. */
  publicFeed?: boolean;
  /** What a message may contain. */
  chat?: {
    allowMedia: boolean;
    allowVoice: boolean;
    allowGroups: boolean;
    typingIndicator: boolean;
    readReceipts: boolean;
  };
  /** The greeting for right now, or null when switched off. */
  greeting?: string | null;
  /** How dates are written, from System settings. */
  datetimeFormat?: string;
  /** What the composer may offer, and how long a post can be. */
  marketplace?: {
    allowOffers: boolean;
    enabled: boolean;
    headline?: string;
    subtitle?: string;
  };
  uploads?: { maxVideoMb: number; maxPhotoMb: number };
  posts?: {
    maxLength: number;
    /** Lines of a long post shown before it folds behind "Read more". 0 = all. */
    linesBeforeMore: number;
    polls: boolean;
    colouredPosts: boolean;
    scheduling: boolean;
    voiceNotes: boolean;
    gifPicker: boolean;
    /** Whether a track on a photo starts muted. */
    musicStartsMuted: boolean;
  };
};

const Ctx = createContext<Site>({ siteName: "XRcoin", tagline: "" });

/**
 * The site's name and tagline, so changing them in admin actually changes
 * what people see rather than only being stored.
 */
export function SiteProvider({ children }: { children: React.ReactNode }) {
  const [site, setSite] = useState<Site>({ siteName: "XRcoin", tagline: "" });

  useEffect(() => {
    fetchOnce<Record<string, never> & Partial<Site> & Record<string, unknown>>("/api/settings")
      .then((d) => d)
      .then((d) => {
        if (d?.siteName) {
          setSite({
            siteName: d.siteName,
            tagline: d.tagline ?? "",
            connectionMode: d.connectionMode === "friend" ? "friend" : "follow",
            siteOnline: d.siteOnline,
            shutdownMessage: d.shutdownMessage,
            publicFeed: d.publicFeed,
            chat: d.chat,
            greeting: d.greeting ?? null,
            datetimeFormat: d.datetimeFormat,
            marketplace: d.marketplace,
            uploads: d.uploads,
            posts: d.posts
              ? {
                  maxLength: Number(d.posts.maxLength ?? 5000),
                  linesBeforeMore: Number(d.posts.linesBeforeMore ?? 4),
                  polls: d.posts.polls !== false,
                  colouredPosts: d.posts.colouredPosts !== false,
                  scheduling: d.posts.scheduling !== false,
                  voiceNotes: d.posts.voiceNotes !== false,
                  gifPicker: d.posts.gifPicker === true,
                  musicStartsMuted: d.posts.musicStartsMuted !== false,
                }
              : undefined,
          });
        }
      })
      .catch(() => {});
  }, []);

  return <Ctx.Provider value={site}>{children}</Ctx.Provider>;
}

export const useSite = () => useContext(Ctx);


/** Post composer limits, with sensible values before settings arrive. */
export function usePostSettings() {
  const { posts } = useSite();
  return (
    posts ?? {
      maxLength: 5000,
      linesBeforeMore: 4,
      polls: true,
      colouredPosts: true,
      scheduling: true,
      voiceNotes: true,
      gifPicker: false,
      musicStartsMuted: true,
    }
  );
}

/**
 * The wording for whichever social model this site runs.
 *
 *   const c = useConnectionWords();
 *   <button>{c.connect}</button>     // "Follow" or "Add friend"
 *
 * Defaults to followers until the settings arrive, which is how the site
 * behaved before this existed — so nothing flickers into a different word
 * on a site that never changed the setting.
 */
export function useConnectionWords(): ConnectionWords {
  const site = useSite();
  return words(site.connectionMode ?? "follow");
}
