import { reactive } from "vue";
import axios from "axios";
import { api, ensureCsrf } from "../services/api";
import { layoutConfig } from "../layout/composables/layout";

import faviconPng from "../assets/branding/favicon.png";
import logoCompact from "../assets/branding/logo-compact.png";
import logoHeader from "../assets/branding/logo-header.png";
import logoSidebarWhite from "../assets/branding/logo-sidebar-white.png";
import loginHeroSvg from "../assets/branding/login-hero.svg";

const xsrfCookie = "XSRF-TOKEN";
const xsrfHeader = "X-XSRF-TOKEN";

/** Bundled Build2Connect defaults — always resolveable via Vite (no dependency on public/). */
export const defaultBrandingUrls = {
  sidebar: logoSidebarWhite,
  header: logoHeader,
  compact: logoCompact,
  favicon: faviconPng,
  loginHero: loginHeroSvg,
};

const LOGO_KEYS = ["sidebar", "header", "compact", "favicon", "loginHero"];

export const appBranding = reactive({ ...defaultBrandingUrls });

/** Resolved from GET /api/app-settings (and PATCH responses); npm + Composer maestro/core versions. */
export const maestroCoreVersions = reactive({
  npm: /** @type {string | null} */ (null),
  composer: /** @type {string | null} */ (null),
});

/** From Superadmin › Huisstijl — custom offer PDF backgrounds (`path` + public `url`). */
export const offerDocumentBackgrounds = reactive(
  /** @type {Array<{ path: string; url: string }>} */ ([]),
);

/** Public homepage settings (readable in Superadmin and host bootstraps). */
export const publicPageSettings = reactive({
  enabled: false,
  mode: "core_default",
  rootMode: "login",
});

/** Login page SSO provider toggles (effective + stored values from API). */
export const loginSettings = reactive({
  providers: {
    microsoft: false,
    google: false,
    apple: false,
  },
  providersStored: {
    microsoft: null,
    google: false,
    apple: false,
  },
  microsoftConfigured: false,
});

export function mergeAppSettingsPayload(data) {
  if (data.theme && typeof data.theme === "object") {
    Object.assign(layoutConfig, data.theme);
  }
  if (data.logos && typeof data.logos === "object") {
    for (const key of LOGO_KEYS) {
      const v = data.logos[key];
      appBranding[key] =
        typeof v === "string" && v.length > 0 ? v : defaultBrandingUrls[key];
    }
  }
  if (data.maestroCore && typeof data.maestroCore === "object") {
    const mc = data.maestroCore;
    maestroCoreVersions.npm =
      typeof mc.npm === "string" && mc.npm.length > 0 ? mc.npm : null;
    maestroCoreVersions.composer =
      typeof mc.composer === "string" && mc.composer.length > 0
        ? mc.composer
        : null;
  }
  if (Array.isArray(data.offerDocumentBackgrounds)) {
    offerDocumentBackgrounds.length = 0;
    for (const row of data.offerDocumentBackgrounds) {
      if (row && typeof row.url === "string" && typeof row.path === "string") {
        offerDocumentBackgrounds.push({ path: row.path, url: row.url });
      }
    }
  }
  if (data.publicPage && typeof data.publicPage === "object") {
    publicPageSettings.enabled = Boolean(data.publicPage.enabled);
    publicPageSettings.mode =
      data.publicPage.mode === "customer_override"
        ? "customer_override"
        : "core_default";
    publicPageSettings.rootMode = ["dashboard", "login", "public"].includes(
      data.publicPage.rootMode,
    )
      ? data.publicPage.rootMode
      : "login";
  }
  if (data.login && typeof data.login === "object") {
    const login = data.login;
    if (login.providers && typeof login.providers === "object") {
      loginSettings.providers.microsoft = Boolean(login.providers.microsoft);
      loginSettings.providers.google = Boolean(login.providers.google);
      loginSettings.providers.apple = Boolean(login.providers.apple);
    }
    if (login.providersStored && typeof login.providersStored === "object") {
      const stored = login.providersStored;
      loginSettings.providersStored.microsoft =
        stored.microsoft === null || stored.microsoft === undefined
          ? null
          : Boolean(stored.microsoft);
      loginSettings.providersStored.google = Boolean(stored.google);
      loginSettings.providersStored.apple = Boolean(stored.apple);
    }
    loginSettings.microsoftConfigured = Boolean(login.microsoftConfigured);
  }
  applyDocumentFavicon(appBranding.favicon);
}

export async function hydrateAppSettings() {
  try {
    const { data } = await api.get("/api/app-settings");
    mergeAppSettingsPayload(data);
  } catch {
    Object.assign(appBranding, defaultBrandingUrls);
    applyDocumentFavicon(defaultBrandingUrls.favicon);
  }
}

export async function persistAppAppearance() {
  await ensureCsrf();
  const { data } = await api.patch("/api/superadmin/app-settings", {
    theme: {
      preset: layoutConfig.preset,
      primary: layoutConfig.primary,
      surface: layoutConfig.surface,
      darkTheme: layoutConfig.darkTheme,
      menuMode: layoutConfig.menuMode,
      menuTheme: layoutConfig.menuTheme,
      cardStyle: layoutConfig.cardStyle,
    },
  });
  mergeAppSettingsPayload(data);
}

export async function persistPublicPageSettings(payload) {
  await ensureCsrf();
  const { data } = await api.patch("/api/superadmin/app-settings", {
    publicPage: {
      enabled: Boolean(payload.enabled),
      mode:
        payload.mode === "customer_override"
          ? "customer_override"
          : "core_default",
      rootMode: ["dashboard", "login", "public"].includes(payload.rootMode)
        ? payload.rootMode
        : "login",
    },
  });
  mergeAppSettingsPayload(data);
}

export async function persistLoginSettings(payload) {
  await ensureCsrf();
  const providers = payload.providers ?? {};
  const microsoft =
    providers.microsoft === null || providers.microsoft === undefined
      ? null
      : Boolean(providers.microsoft);
  const { data } = await api.patch("/api/superadmin/app-settings", {
    login: {
      providers: {
        microsoft,
        google: Boolean(providers.google),
        apple: Boolean(providers.apple),
      },
    },
  });
  mergeAppSettingsPayload(data);
}

export async function postBrandingUpload(formData) {
  await ensureCsrf();
  return axios.post("/api/superadmin/branding", formData, {
    baseURL: api.defaults.baseURL,
    withCredentials: true,
    xsrfCookieName: xsrfCookie,
    xsrfHeaderName: xsrfHeader,
    headers: {
      Accept: "application/json",
      "X-Requested-With": "XMLHttpRequest",
    },
  });
}

export async function deleteBrandingSlot(slot) {
  await ensureCsrf();
  const { data } = await api.delete(`/api/superadmin/branding/${slot}`);
  mergeAppSettingsPayload(data);
}

export async function postOfferDocumentBackgroundUpload(formData) {
  await ensureCsrf();
  return axios.post(
    "/api/superadmin/branding/offer-document-background",
    formData,
    {
      baseURL: api.defaults.baseURL,
      withCredentials: true,
      xsrfCookieName: xsrfCookie,
      xsrfHeaderName: xsrfHeader,
      headers: {
        Accept: "application/json",
        "X-Requested-With": "XMLHttpRequest",
      },
    },
  );
}

export async function deleteOfferDocumentBackground(index) {
  await ensureCsrf();
  const { data } = await api.delete(
    `/api/superadmin/branding/offer-document-background/${index}`,
  );
  mergeAppSettingsPayload(data);
}

function applyDocumentFavicon(href) {
  if (typeof document === "undefined" || !href) {
    return;
  }
  let link = document.querySelector('link[rel="icon"]');
  if (!link) {
    link = document.createElement("link");
    link.rel = "icon";
    link.type = "image/png";
    document.head.appendChild(link);
  }
  link.href = href;
}
