/**
 * Settings Page Component
 *
 * Admin settings page for Opus Price Builder.
 * Manages Google Fonts local loading. Pro AI settings are rendered via extension slot.
 */


import * as Switch from "@radix-ui/react-switch";
import {
  ReloadIcon,
  GearIcon,
  FontFamilyIcon,
  ExclamationTriangleIcon,
} from "@radix-ui/react-icons";

import { ExtensionSlot } from "@/components/Slots/ExtensionSlot";
import { useSettings, useUpdateSettings, useUpdateFonts } from "@/hooks/useSettings";
import { useToast } from "@/hooks/useToast";
import { useSettingsStore } from "@/stores/settingsStore";
import { useLayouts } from "@/hooks/useLayouts";
import { extractGoogleFontsWithVariants, type FontsMap } from "@/utils/fontUtils";
import { getErrorMessage } from "@/utils/errorMessage";
import { isPro } from "@/utils/license";

export function SettingsPage() {
  const { isLoading, isError, error } = useSettings();
  const updateSettings = useUpdateSettings();
  const updateFonts = useUpdateFonts();
  const toast = useToast();
  const { data: layoutsData } = useLayouts({ perPage: 100 });

  const {
    googleFontsLocal,
    googleFontsCdn,
    googleFontsDisabled,
    aiProvider,
    aiApiKeyDraft,
    aiApiKeyClearRequested,
    aiModel,
    isSaving,
    isUpdatingFonts,
    setGoogleFontsLocal,
    setGoogleFontsCdn,
    setGoogleFontsDisabled,
    setAiApiKeyClearRequested,
  } = useSettingsStore();

  const handleSave = async () => {
    const payload: Record<string, unknown> = {
      google_fonts_local: googleFontsLocal,
      google_fonts_cdn: googleFontsCdn,
      google_fonts_disabled: googleFontsDisabled,
    };

    if (isPro()) {
      payload.ai_provider = aiProvider;
      payload.ai_model = aiProvider === "none" ? "" : aiModel;

      if (aiApiKeyClearRequested) {
        payload.clear_ai_api_key = true;
      } else if (aiApiKeyDraft.trim() !== "") {
        payload.ai_api_key = aiApiKeyDraft.trim();
      }
    }

    try {
      await updateSettings.mutateAsync(payload);
      setAiApiKeyClearRequested(false);
      toast.success("Settings saved", { description: "Your changes were stored successfully." });
    } catch (err) {
      toast.error("Failed to save settings", { description: getErrorMessage(err) });
    }
  };

  const handleUpdateFonts = async () => {

    const allFonts: FontsMap = {};
    if (layoutsData?.data) {
      for (const layout of layoutsData.data) {
        if (layout.canvasData?.elements) {
          const fonts = extractGoogleFontsWithVariants(layout.canvasData.elements);
          for (const [fontName, fontInfo] of Object.entries(fonts)) {
            if (!allFonts[fontName]) {
              allFonts[fontName] = { weights: [], styles: [] };
            }
            for (const weight of fontInfo.weights) {
              if (!allFonts[fontName].weights.includes(weight)) {
                allFonts[fontName].weights.push(weight);
              }
            }
            for (const style of fontInfo.styles) {
              if (!allFonts[fontName].styles.includes(style)) {
                allFonts[fontName].styles.push(style);
              }
            }
          }
        }
      }
    }

    const fontCount = Object.keys(allFonts).length;

    if (fontCount === 0) {
      toast.error("No fonts to update", { description: "No Google fonts found in saved layouts." });
      return;
    }

    for (const fontName of Object.keys(allFonts)) {
      allFonts[fontName].weights.sort((a, b) => a - b);
    }

    try {
      const result = await updateFonts.mutateAsync({ fonts: allFonts, googleFontsLocal: true });
      const downloadedCount = Object.keys(result.downloaded).length;
      const skippedCount = Object.keys(result.skipped).length;
      const errorCount = Object.keys(result.errors).length;

      if (errorCount > 0) {
        toast.error("Font update incomplete", {
          description: `Downloaded ${downloadedCount} fonts, ${errorCount} failed: ${Object.keys(result.errors).join(", ")}`,
        });
      } else if (downloadedCount === 0 && skippedCount > 0) {
        toast.success("Fonts already up to date", {
          description: `All ${skippedCount} fonts already exist locally.`,
        });
      } else {
        const skippedMsg = skippedCount > 0 ? `, ${skippedCount} already existed` : "";
        toast.success("Fonts updated", {
          description: `Downloaded ${downloadedCount} fonts${skippedMsg}.`,
        });
      }
    } catch (err) {
      toast.error("Failed to update fonts", { description: getErrorMessage(err) });
    }
  };

  if (isLoading) {
    return (
      <div className="oppb-settings-page">
        <div className="oppb-settings-loading">
          <ReloadIcon className="w-6 h-6 animate-spin" />
          <span>Loading settings...</span>
        </div>
      </div>
    );
  }

  if (isError) {
    return (
      <div className="oppb-settings-page">
        <div className="oppb-settings-error">
          <ExclamationTriangleIcon className="w-6 h-6" />
          <span>Failed to load settings: {error?.message}</span>
        </div>
      </div>
    );
  }

  return (
    <div className="oppb-settings-page">
      <header className="oppb-settings-header">
        <div className="oppb-settings-header__title">
          <GearIcon className="w-6 h-6" />
          <h1>Price Builder Settings</h1>
        </div>
        <p className="oppb-settings-header__description">Configure Google Fonts loading and AI-powered layout generation.</p>
      </header>

      <div className="oppb-settings-content">
        <section className="oppb-settings-section">
          <div className="oppb-settings-section__header">
            <FontFamilyIcon className="w-5 h-5" />
            <h2>Google Fonts</h2>
          </div>

          <div className="oppb-settings-card">
            <div className="oppb-settings-row">
              <div className="oppb-settings-row__info">
                <label htmlFor="google-fonts-local" className="oppb-settings-row__label">
                  Load fonts locally
                </label>
                <p className="oppb-settings-row__description">
                  Download and serve Google fonts from your server instead of Google&apos;s CDN. Enabled by default for visitor privacy.
                  Use <strong>Update Fonts</strong> below to download fonts used in your layouts.
                </p>
              </div>
              <Switch.Root
                id="google-fonts-local"
                checked={googleFontsLocal}
                onCheckedChange={setGoogleFontsLocal}
                disabled={googleFontsDisabled}
                className="oppb-switch"
              >
                <Switch.Thumb className="oppb-switch__thumb" />
              </Switch.Root>
            </div>

            {googleFontsLocal && (
              <div className="oppb-settings-row oppb-settings-row--nested">
                <div className="oppb-settings-row__info">
                  <span className="oppb-settings-row__label">Update font files</span>
                  <p className="oppb-settings-row__description">Download Google fonts used in your saved layouts.</p>
                </div>
                <button type="button" className="oppb-button oppb-button--secondary" onClick={handleUpdateFonts} disabled={isUpdatingFonts}>
                  {isUpdatingFonts ? (
                    <>
                      <ReloadIcon className="w-4 h-4 animate-spin" />
                      Updating...
                    </>
                  ) : (
                    <>
                      <ReloadIcon className="w-4 h-4" />
                      Update Fonts
                    </>
                  )}
                </button>
              </div>
            )}

            <div className="oppb-settings-row">
              <div className="oppb-settings-row__info">
                <label htmlFor="google-fonts-cdn" className="oppb-settings-row__label">
                  Load fonts from Google CDN
                </label>
                <p className="oppb-settings-row__description">
                  Opt in to load Google fonts directly from Google&apos;s servers for site visitors. When enabled, visitors&apos; browsers
                  may send their IP address and browser information to Google. Disabled by default.
                </p>
              </div>
              <Switch.Root
                id="google-fonts-cdn"
                checked={googleFontsCdn}
                onCheckedChange={setGoogleFontsCdn}
                disabled={googleFontsDisabled}
                className="oppb-switch"
              >
                <Switch.Thumb className="oppb-switch__thumb" />
              </Switch.Root>
            </div>

            <div className="oppb-settings-row">
              <div className="oppb-settings-row__info">
                <label htmlFor="google-fonts-disabled" className="oppb-settings-row__label">
                  Disable font loading
                </label>
                <p className="oppb-settings-row__description">
                  Don&apos;t load Google fonts automatically. Enable this if you want to load fonts yourself via your theme or another plugin.
                </p>
              </div>
              <Switch.Root
                id="google-fonts-disabled"
                checked={googleFontsDisabled}
                onCheckedChange={setGoogleFontsDisabled}
                className="oppb-switch"
              >
                <Switch.Thumb className="oppb-switch__thumb" />
              </Switch.Root>
            </div>
          </div>
        </section>

        <ExtensionSlot name="settings-ai-section" />
      </div>

      <footer className="oppb-settings-footer">
        <div className="oppb-settings-footer__actions">
          <button type="button" className="oppb-button oppb-button--primary" onClick={handleSave} disabled={isSaving}>
            {isSaving ? (
              <>
                <ReloadIcon className="w-4 h-4 animate-spin" />
                Saving...
              </>
            ) : (
              "Save Settings"
            )}
          </button>
        </div>
      </footer>
    </div>
  );
}

export default SettingsPage;
