<script setup>
import { useLayout } from "./composables/layout";
import { $t, updatePreset, updateSurfacePalette } from "@primeuix/themes";
import Aura from "@primeuix/themes/aura";
import Lara from "@primeuix/themes/lara";
import Nora from "@primeuix/themes/nora";
import { computed, ref, watch } from "vue";

import BaseRadioButton from "../components/base/BaseRadioButton.vue";
import BaseSelectButton from "../components/base/BaseSelectButton.vue";
import {
  buildPresetExtension,
  PRIMARY_PRESETS,
  resolveSurfacePalette,
  SURFACE_PRESETS,
} from "../lib/themePalettes.js";

const { layoutState, layoutConfig, isDarkTheme, changeMenuMode } = useLayout();

defineProps({
  location: {
    type: String,
    default: "app",
  },
  simple: {
    type: Boolean,
    default: false,
  },
});

const presets = {
  Aura,
  Lara,
  Nora,
};
const presetOptions = ref(Object.keys(presets));
const preset = ref(layoutConfig.preset);
const themeOptions = ref([
  { name: "Light", value: false },
  { name: "Dark", value: true },
]);
const menuThemeOptions = computed(() => {
  if (isDarkTheme.value) {
    return [
      { name: "Dark", value: "dark" },
      { name: "Primary", value: "primary" },
    ];
  } else {
    return [
      { name: "Light", value: "light" },
      { name: "Dark", value: "dark" },
      { name: "Primary", value: "primary" },
    ];
  }
});
const cardStyleOptions = ref([
  { name: "Transparent", value: "transparent" },
  { name: "Filled", value: "filled" },
]);
const darkTheme = ref(layoutConfig.darkTheme);
const menuMode = ref(layoutConfig.menuMode);
const menuTheme = computed(() => layoutConfig.menuTheme);
const cardStyle = computed(() => layoutConfig.cardStyle);

const primaryColors = ref(PRIMARY_PRESETS);
const surfaces = ref(SURFACE_PRESETS);

function executeDarkModeToggle() {
  layoutConfig.darkTheme = !layoutConfig.darkTheme;
  document.documentElement.classList.toggle("app-dark");
}

function handleToggleDarkMode() {
  if (!document.startViewTransition) {
    executeDarkModeToggle();

    return;
  }

  document.startViewTransition(() => {
    executeDarkModeToggle();
  });
}

function updateColors(type, color) {
  if (type === "primary") {
    layoutConfig.primary = color.name;
  } else if (type === "surface") {
    layoutConfig.surface = color.name;
  }

  applyTheme(type, color);
}

function applyTheme(type, color) {
  if (type === "primary") {
    updatePreset(getPresetExt());
  } else if (type === "surface") {
    updateSurfacePalette(color.palette);
  }
}

function onPresetChange() {
  layoutConfig.preset = preset.value;
  const presetValue = presets[preset.value];
  const surfacePalette = resolveSurfacePalette(
    layoutConfig.surface,
    layoutConfig.surfaceCustom,
  );

  $t()
    .preset(presetValue)
    .preset(getPresetExt())
    .surfacePalette(surfacePalette)
    .use({ useDefaultOptions: true });
}

function onMenuThemeChange(event) {
  layoutConfig.menuTheme = event.value;
}

function onCardStyleChange(event) {
  layoutConfig.cardStyle = event.value;
}

function getPresetExt() {
  return buildPresetExtension(layoutConfig.primary, layoutConfig.primaryCustom);
}

watch(isDarkTheme, (newValue) => {
  if (newValue && menuTheme.value === "light") {
    layoutConfig.menuTheme = "dark";
  }
});
</script>

<template>
  <Drawer
    v-model:visible="layoutState.configSidebarVisible"
    position="right"
    header="Settings"
    class="layout-config-sidebar w-80"
    :pt="{
      pcCloseButton: { root: 'ml-auto' },
    }"
  >
    <div class="flex flex-col gap-6">
      <div>
        <span class="text-lg text-muted-color font-semibold">Primary</span>
        <div class="pt-2 flex gap-2 flex-wrap">
          <button
            v-for="primaryColor of primaryColors"
            :key="primaryColor.name"
            type="button"
            class="w-6 h-6 cursor-pointer hover:shadow-lg rounded duration-150 flex items-center justify-center"
            :style="{
              backgroundColor: `${primaryColor.name === 'noir' ? 'var(--text-color)' : primaryColor.palette['500']}`,
            }"
            @click="updateColors('primary', primaryColor)"
          >
            <i
              v-if="primaryColor.name === layoutConfig.primary"
              class="pi pi-check text-white"
            />
          </button>
        </div>
      </div>

      <div>
        <span class="text-lg text-muted-color font-semibold">Surface</span>
        <div class="pt-2 flex gap-2 flex-wrap">
          <button
            v-for="surface of surfaces"
            :key="surface.name"
            type="button"
            class="w-6 h-6 cursor-pointer hover:shadow-lg rounded duration-150 flex items-center justify-center"
            :style="{ backgroundColor: `${surface.palette['500']}` }"
            @click="updateColors('surface', surface)"
          >
            <i
              v-if="
                layoutConfig.surface
                  ? layoutConfig.surface === surface.name
                  : isDarkTheme
                    ? surface.name === 'zinc'
                    : surface.name === 'slate'
              "
              class="pi pi-check text-white"
            />
          </button>
        </div>
      </div>

      <div>
        <div class="flex flex-col gap-2">
          <span class="text-lg text-muted-color font-semibold">Presets</span>
          <BaseSelectButton
            v-model="preset"
            :options="presetOptions"
            :allow-empty="false"
            @change="onPresetChange"
          />
        </div>
      </div>

      <div>
        <div class="flex flex-col gap-2">
          <span class="text-lg text-muted-color font-semibold"
            >Color Scheme</span
          >
          <BaseSelectButton
            v-model="darkTheme"
            :options="themeOptions"
            option-label="name"
            option-value="value"
            :allow-empty="false"
            @change="handleToggleDarkMode"
          />
        </div>
      </div>

      <div v-if="!simple && location === 'app'" class="flex flex-col gap-2">
        <span class="text-lg text-muted-color font-semibold">Card Style</span>
        <BaseSelectButton
          :model-value="cardStyle"
          :options="cardStyleOptions"
          :allow-empty="false"
          option-label="name"
          option-value="value"
          @change="onCardStyleChange"
        />
      </div>

      <div v-if="!simple && location === 'app'" class="flex flex-col gap-2">
        <span class="text-lg text-muted-color font-semibold">Menu Theme</span>
        <BaseSelectButton
          :model-value="menuTheme"
          :options="menuThemeOptions"
          :allow-empty="false"
          option-label="name"
          option-value="value"
          @change="onMenuThemeChange"
        />
      </div>

      <div v-if="!simple && location === 'app'">
        <div class="flex flex-col gap-2">
          <span class="text-lg text-muted-color font-semibold">Menu Type</span>
          <div class="flex flex-wrap flex-col gap-3">
            <div class="flex">
              <div class="flex items-center gap-2 w-6/12">
                <BaseRadioButton
                  v-model="menuMode"
                  name="menuMode"
                  value="static"
                  input-id="static"
                  @update:model-value="changeMenuMode"
                />
                <label for="static">Static</label>
              </div>

              <div class="flex items-center gap-2 w-6/12">
                <BaseRadioButton
                  v-model="menuMode"
                  name="menuMode"
                  value="overlay"
                  input-id="overlay"
                  @update:model-value="changeMenuMode"
                />
                <label for="overlay">Overlay</label>
              </div>
            </div>
            <div class="flex">
              <div class="flex items-center gap-2 w-6/12">
                <BaseRadioButton
                  v-model="menuMode"
                  name="menuMode"
                  value="slim"
                  input-id="slim"
                  @update:model-value="changeMenuMode"
                />
                <label for="slim">Slim</label>
              </div>
              <div class="flex items-center gap-2 w-6/12">
                <BaseRadioButton
                  v-model="menuMode"
                  name="menuMode"
                  value="compact"
                  input-id="compact"
                  @update:model-value="changeMenuMode"
                />
                <label for="compact">Compact</label>
              </div>
            </div>
            <div class="flex">
              <div class="flex items-center gap-2 w-6/12">
                <BaseRadioButton
                  v-model="menuMode"
                  name="menuMode"
                  value="reveal"
                  input-id="reveal"
                  @update:model-value="changeMenuMode"
                />
                <label for="reveal">Reveal</label>
              </div>
              <div class="flex items-center gap-2 w-6/12">
                <BaseRadioButton
                  v-model="menuMode"
                  name="menuMode"
                  value="drawer"
                  input-id="drawer"
                  @update:model-value="changeMenuMode"
                />
                <label for="drawer">Drawer</label>
              </div>
            </div>
            <div class="flex">
              <div class="flex items-center gap-2 w-6/12">
                <BaseRadioButton
                  v-model="menuMode"
                  name="menuMode"
                  value="horizontal"
                  input-id="horizontal"
                  @update:model-value="changeMenuMode"
                />
                <label for="horizontal">Horizontal</label>
              </div>
              <div class="flex items-center gap-2 w-6/12">
                <BaseRadioButton
                  v-model="menuMode"
                  name="menuMode"
                  value="maestro"
                  input-id="maestro"
                  @update:model-value="changeMenuMode"
                />
                <label for="maestro">Maestro</label>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </Drawer>
</template>
