<script setup>
import BaseButton from "../../components/base/BaseButton.vue";
import BaseToggleSwitch from "../../components/base/BaseToggleSwitch.vue";
import { useBaseToast } from "../../composables/useBaseToast.js";
import { computed, onMounted, ref } from "vue";
import {
  appBranding,
  defaultBrandingUrls,
  deleteBrandingSlot,
  deleteOfferDocumentBackground,
  hydrateAppSettings,
  loginSettings,
  mergeAppSettingsPayload,
  offerDocumentBackgrounds,
  persistLoginSettings,
  postBrandingUpload,
  postOfferDocumentBackgroundUpload,
} from "../../composables/useAppSettings";
import { apiErrorDetail } from "../../services/api";

const toast = useBaseToast();

const uploading = ref(null);
const savingLogin = ref(false);

const microsoftEnabled = ref(false);
const googleEnabled = ref(false);
const appleEnabled = ref(false);

const canSaveLogin = computed(
  () =>
    microsoftEnabled.value !== loginSettings.providers.microsoft ||
    googleEnabled.value !== loginSettings.providers.google ||
    appleEnabled.value !== loginSettings.providers.apple,
);

function syncLoginFormFromSettings() {
  microsoftEnabled.value = loginSettings.providers.microsoft;
  googleEnabled.value = loginSettings.providers.google;
  appleEnabled.value = loginSettings.providers.apple;
}

onMounted(async () => {
  await hydrateAppSettings();
  syncLoginFormFromSettings();
});

async function saveLoginSettings() {
  savingLogin.value = true;
  try {
    await persistLoginSettings({
      providers: {
        microsoft: microsoftEnabled.value ? null : false,
        google: googleEnabled.value,
        apple: appleEnabled.value,
      },
    });
    syncLoginFormFromSettings();
    toast.add({
      severity: "success",
      summary: "Opgeslagen",
      detail: "Loginpagina-instellingen bijgewerkt.",
      life: 3000,
    });
  } catch (error) {
    toast.add({
      severity: "error",
      summary: "Opslaan mislukt",
      detail: apiErrorDetail(error),
      life: 6500,
    });
  } finally {
    savingLogin.value = false;
  }
}

const slots = [
  {
    key: "sidebar",
    title: "Sidebar logo",
    hint: "White / high-contrast lockup for colored sidebar backgrounds.",
  },
  {
    key: "header",
    title: "Header logo",
    hint: "Full-color lockup for light toolbars and login screens.",
  },
  {
    key: "compact",
    title: "Compact mark",
    hint: "Icon-style mark when the sidebar is collapsed.",
  },
  {
    key: "favicon",
    title: "Favicon",
    hint: "Browser tab icon (PNG, ICO, or SVG recommended).",
  },
  {
    key: "loginHero",
    title: "Login hero image",
    hint:
      "Large illustration on the login screen’s right panel (matches the Sakai / Top-Level-Punt-style layout).",
    largePreview: true,
  },
];

async function onPickFile(slot, event) {
  const input = event.target;
  const file = input.files?.[0];
  input.value = "";
  if (!file) {
    return;
  }

  uploading.value = slot;
  try {
    const fd = new FormData();
    fd.append("slot", slot);
    fd.append("file", file);
    const { data } = await postBrandingUpload(fd);
    mergeAppSettingsPayload(data);
    toast.add({
      severity: "success",
      summary: "Uploaded",
      detail: `${slot} branding updated.`,
      life: 3000,
    });
  } catch (error) {
    toast.add({
      severity: "error",
      summary: "Upload failed",
      detail: apiErrorDetail(error),
      life: 6500,
    });
  } finally {
    uploading.value = null;
  }
}

function triggerPick(slot) {
  document.getElementById(`brand-upload-${slot}`)?.click();
}

async function clearSlot(slot) {
  uploading.value = slot;
  try {
    await deleteBrandingSlot(slot);
    toast.add({
      severity: "success",
      summary: "Reset",
      detail: `${slot} restored to Core default.`,
      life: 3000,
    });
  } catch (error) {
    toast.add({
      severity: "error",
      summary: "Could not reset",
      detail: apiErrorDetail(error),
      life: 6500,
    });
  } finally {
    uploading.value = null;
  }
}

function previewUrl(slot) {
  return appBranding[slot] ?? defaultBrandingUrls[slot];
}

async function onPickOfferBackground(event) {
  const input = event.target;
  const file = input.files?.[0];
  input.value = "";
  if (!file) {
    return;
  }
  uploading.value = "offerBg";
  try {
    const fd = new FormData();
    fd.append("file", file);
    const { data } = await postOfferDocumentBackgroundUpload(fd);
    mergeAppSettingsPayload(data);
    toast.add({
      severity: "success",
      summary: "Uploaded",
      detail: "Offer background added. Browse and pick it when editing an offer.",
      life: 4000,
    });
  } catch (error) {
    toast.add({
      severity: "error",
      summary: "Upload failed",
      detail: apiErrorDetail(error),
      life: 6500,
    });
  } finally {
    uploading.value = null;
  }
}

function triggerOfferBgPick() {
  document.getElementById("brand-upload-offer-bg")?.click();
}

async function clearOfferBackgroundAt(index) {
  uploading.value = "offerBg";
  try {
    await deleteOfferDocumentBackground(index);
    toast.add({
      severity: "success",
      summary: "Removed",
      detail: "Custom offer background deleted.",
      life: 3000,
    });
  } catch (error) {
    toast.add({
      severity: "error",
      summary: "Could not remove",
      detail: apiErrorDetail(error),
      life: 6500,
    });
  } finally {
    uploading.value = null;
  }
}
</script>

<template>
  <div class="flex flex-col gap-6">
    <div>
      <h2 class="title-h6 text-surface-900 dark:text-surface-0 mb-1">
        Branding
      </h2>
      <p class="body-small text-surface-600 dark:text-surface-400">
        Defaults ship Build2Connect assets from Core. Upload overrides here for
        the whole application (stored per instance).
      </p>
    </div>

    <div class="flex flex-col gap-8">
      <section
        class="border border-surface-200 dark:border-surface-700 rounded-lg p-4 flex flex-col gap-4"
      >
        <div>
          <span class="font-semibold text-surface-900 dark:text-surface-0"
            >Loginpagina</span
          >
          <p class="body-small text-surface-600 dark:text-surface-400 mb-0 mt-1">
            Social login-knoppen op het inlogscherm. Microsoft wordt automatisch
            aangeboden wanneer SSO in de omgeving is geconfigureerd, tenzij je
            het hier uitschakelt.
          </p>
        </div>

        <div class="flex flex-col gap-4">
          <div class="flex items-center justify-between gap-4">
            <div class="min-w-0">
              <span class="text-surface-900 dark:text-surface-0"
                >Microsoft</span
              >
              <p
                v-if="!loginSettings.microsoftConfigured"
                class="body-small text-surface-500 dark:text-surface-400 mb-0 mt-0.5"
              >
                Configureer Microsoft SSO in de omgeving om deze knop te tonen.
              </p>
            </div>
            <BaseToggleSwitch
              v-model="microsoftEnabled"
              :disabled="!loginSettings.microsoftConfigured"
            />
          </div>

          <div class="flex items-center justify-between gap-4">
            <div class="min-w-0">
              <span class="text-surface-900 dark:text-surface-0">Google</span>
              <p class="body-small text-surface-500 dark:text-surface-400 mb-0 mt-0.5">
                Placeholder — nog geen backend.
              </p>
            </div>
            <BaseToggleSwitch v-model="googleEnabled" />
          </div>

          <div class="flex items-center justify-between gap-4">
            <div class="min-w-0">
              <span class="text-surface-900 dark:text-surface-0">Apple</span>
              <p class="body-small text-surface-500 dark:text-surface-400 mb-0 mt-0.5">
                Placeholder — nog geen backend.
              </p>
            </div>
            <BaseToggleSwitch v-model="appleEnabled" />
          </div>
        </div>

        <div class="flex justify-end">
          <BaseButton
            type="button"
            label="Login-instellingen opslaan"
            icon="save"
            size="small"
            :loading="savingLogin"
            :disabled="!canSaveLogin"
            @click="saveLoginSettings"
          />
        </div>
      </section>

      <section
        class="border border-surface-200 dark:border-surface-700 rounded-lg p-4 flex flex-col gap-3"
      >
        <div>
          <span class="font-semibold text-surface-900 dark:text-surface-0"
            >Offer document backgrounds</span
          >
          <p class="body-small text-surface-600 dark:text-surface-400 mb-0 mt-1">
            Optional full-page backgrounds for shared offers and PDFs. After
            upload, select them in Offerte bewerken › right panel. JPG, PNG, or
            WebP (max 8&nbsp;MB).
          </p>
        </div>
        <div class="flex flex-wrap gap-2 items-center">
          <input
            type="file"
            accept=".png,.jpg,.jpeg,.webp"
            class="hidden"
            id="brand-upload-offer-bg"
            @change="onPickOfferBackground"
          />
          <BaseButton
            type="button"
            variant="secondary"
            :loading="uploading === 'offerBg'"
            label="Upload background"
            icon="upload"
            size="small"
            @click="triggerOfferBgPick"
          />
        </div>
        <div
          v-if="offerDocumentBackgrounds.length"
          class="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 gap-3"
        >
          <div
            v-for="(item, idx) in offerDocumentBackgrounds"
            :key="item.path"
            class="group relative rounded-md overflow-hidden border border-surface-200 dark:border-surface-600 aspect-video bg-surface-100 dark:bg-surface-800"
          >
            <img
              :src="item.url"
              alt=""
              class="w-full h-full object-cover"
            />
            <div
              class="absolute inset-0 bg-black/0 group-hover:bg-black/40 transition-colors flex items-end justify-end p-1.5"
            >
              <BaseButton
                type="button"
                variant="secondary"
                text
                icon="trash"
                size="small"
                class="!text-white opacity-0 group-hover:opacity-100"
                :loading="uploading === 'offerBg'"
                @click="clearOfferBackgroundAt(idx)"
              />
            </div>
          </div>
        </div>
      </section>

      <section
        v-for="item in slots"
        :key="item.key"
        class="border border-surface-200 dark:border-surface-700 rounded-lg p-4 flex flex-col gap-3 sm:flex-row sm:items-start"
      >
        <div
          class="flex-shrink-0 flex items-center justify-center bg-surface-100 dark:bg-surface-900 rounded-md p-4"
          :class="
            item.largePreview
              ? 'min-h-[12rem] min-w-[14rem]'
              : 'min-h-[5rem] min-w-[8rem]'
          "
        >
          <img
            :src="previewUrl(item.key)"
            :alt="item.title"
            :class="
              item.largePreview
                ? 'max-h-48 max-w-[16rem] w-full object-contain'
                : 'max-h-14 max-w-[7rem] object-contain'
            "
          />
        </div>
        <div class="flex-1 min-w-0 flex flex-col gap-2">
          <div>
            <span class="font-semibold text-surface-900 dark:text-surface-0">{{
              item.title
            }}</span>
            <p class="body-small text-surface-600 dark:text-surface-400 mb-0 mt-1">
              {{ item.hint }}
            </p>
          </div>
          <div class="flex flex-wrap gap-2 items-center">
            <input
              type="file"
              :accept="
                item.key === 'favicon'
                  ? '.png,.ico,.svg,.webp,.gif,.jpg,.jpeg'
                  : '.png,.jpg,.jpeg,.webp,.svg,.gif'
              "
              class="hidden"
              :id="`brand-upload-${item.key}`"
              @change="onPickFile(item.key, $event)"
            />
            <BaseButton
              type="button"
              variant="secondary"
              :loading="uploading === item.key"
              label="Upload"
              icon="upload"
              size="small"
              @click="triggerPick(item.key)"
            />
            <BaseButton
              variant="secondary"
              label="Reset to Core default"
              icon="replay"
              size="small"
              text
              :loading="uploading === item.key"
              @click="clearSlot(item.key)"
            />
          </div>
        </div>
      </section>
    </div>
  </div>
</template>
