<script setup lang="ts">
import type { ToolbarType } from './types';

import { computed, onBeforeUnmount, onMounted, ref } from 'vue';
import { useRoute } from 'vue-router';

import { $t } from '@easyflow/locales';
import { preferences, usePreferences } from '@easyflow/preferences';

import { Copyright } from '../basic/copyright';
import AuthenticationFormView from './form.vue';
import Toolbar from './toolbar.vue';

interface Props {
  appName?: string;
  logo?: string;
  logoDark?: string;
  pageTitle?: string;
  pageDescription?: string;
  toolbar?: boolean;
  copyright?: boolean;
  toolbarList?: ToolbarType[];
  clickLogo?: () => void;
}

const props = withDefaults(defineProps<Props>(), {
  appName: '',
  copyright: true,
  logo: '',
  logoDark: '',
  pageDescription: '',
  pageTitle: '',
  toolbar: true,
  toolbarList: () => ['language', 'theme'],
  clickLogo: () => {},
});

const { isDark } = usePreferences();
const route = useRoute();

const logoSrc = computed(() => {
  if (isDark.value && props.logoDark) {
    return props.logoDark;
  }
  return props.logo;
});

const activeCapabilityIndex = ref(0);
let capabilityTimer: null | number = null;
const currentHour = ref(new Date().getHours());

const isLoginRoute = computed(() => route.path === '/auth/login');
const capabilityLabels = computed(() => [
  $t('authentication.capabilityModel'),
  $t('authentication.capabilityAgent'),
  $t('authentication.capabilityWorkflow'),
  $t('authentication.capabilityKnowledge'),
]);

const stageGreeting = computed(() => {
  if (currentHour.value >= 5 && currentHour.value < 11) {
    return $t('authentication.greetingMorning');
  }
  if (currentHour.value >= 11 && currentHour.value < 14) {
    return $t('authentication.greetingNoon');
  }
  if (currentHour.value >= 14 && currentHour.value < 18) {
    return $t('authentication.greetingAfternoon');
  }
  return $t('authentication.greetingEvening');
});

onMounted(() => {
  capabilityTimer = window.setInterval(() => {
    activeCapabilityIndex.value =
      (activeCapabilityIndex.value + 1) % capabilityLabels.value.length;
  }, 2400);
});

onBeforeUnmount(() => {
  if (capabilityTimer) {
    clearInterval(capabilityTimer);
  }
});
</script>

<template>
  <div
    :class="[isDark ? 'dark' : '']"
    class="auth-shell relative flex min-h-full flex-1 select-none overflow-hidden"
  >
    <div class="auth-shell-grid absolute inset-0"></div>
    <div class="auth-shell-noise absolute inset-0"></div>
    <div class="auth-glow auth-glow-primary"></div>
    <div class="auth-glow auth-glow-secondary"></div>
    <div class="auth-glow auth-glow-tertiary"></div>

    <template v-if="toolbar">
      <slot name="toolbar">
        <Toolbar :toolbar-list="toolbarList" />
      </slot>
    </template>

    <slot name="logo">
      <div
        v-if="logoSrc || appName"
        class="absolute left-0 top-0 z-20 flex flex-1"
        @click="clickLogo"
      >
        <div
          class="auth-brand-chip text-foreground ml-4 mt-4 flex items-center sm:ml-6 sm:mt-6"
        >
          <img
            v-if="logoSrc"
            :key="logoSrc"
            :alt="appName"
            :src="logoSrc"
            class="mr-2.5"
            width="112"
          />
          <span v-else class="auth-brand-name">{{ appName }}</span>
        </div>
      </div>
    </slot>

    <main
      class="auth-stage relative z-10 flex min-h-full w-full items-center justify-center px-6 pb-10 pt-28 sm:px-10 sm:pt-32"
    >
      <div
        class="auth-stage-inner mx-auto flex w-full max-w-[1080px] flex-col items-center"
      >
        <div
          v-if="isLoginRoute"
          class="auth-stage-copy w-full max-w-[780px] text-center"
        >
          <h1 class="auth-page-title text-foreground">
            {{ stageGreeting }}
          </h1>
          <div
            class="auth-stage-switcher text-muted-foreground"
            aria-label="同一入口能力切换"
          >
            <span class="auth-stage-switcher-label">在同一入口管理</span>
            <span class="auth-stage-pill" aria-live="polite">
              <Transition mode="out-in" name="auth-pill">
                <span
                  :key="capabilityLabels[activeCapabilityIndex]"
                  class="auth-stage-pill-text"
                >
                  {{ capabilityLabels[activeCapabilityIndex] }}
                </span>
              </Transition>
            </span>
          </div>
        </div>

        <AuthenticationFormView
          class="auth-window-host w-full"
          :class="[
            isLoginRoute ? 'max-w-[25rem] sm:max-w-[26rem]' : 'max-w-[31rem]',
            isLoginRoute ? 'mt-8 sm:mt-10' : 'mt-0 sm:mt-4',
          ]"
          data-side="bottom"
        >
          <template v-if="copyright" #copyright>
            <slot name="copyright">
              <Copyright
                v-if="preferences.copyright.enable"
                v-bind="preferences.copyright"
              />
            </slot>
          </template>
        </AuthenticationFormView>
      </div>
    </main>
  </div>
</template>

<style scoped>
.auth-shell {
  background:
    radial-gradient(
      circle at top,
      rgb(255 255 255 / 78%),
      rgb(255 255 255 / 0%) 36%
    ),
    linear-gradient(180deg, #f7faff 0%, #eef4fd 55%, #edf3fb 100%);
}

.auth-shell-grid {
  background-image:
    linear-gradient(rgb(13 74 160 / 6%) 1px, transparent 1px),
    linear-gradient(90deg, rgb(13 74 160 / 6%) 1px, transparent 1px);
  background-position: center center;
  background-size: 120px 120px;
  opacity: 0.42;
  mask-image: linear-gradient(180deg, rgb(0 0 0 / 28%), transparent 75%);
}

.auth-shell-noise {
  background-image:
    radial-gradient(
      circle at 20% 20%,
      rgb(255 255 255 / 35%) 0 0.9px,
      transparent 1.2px
    ),
    radial-gradient(
      circle at 80% 30%,
      rgb(255 255 255 / 22%) 0 1px,
      transparent 1.3px
    ),
    radial-gradient(
      circle at 40% 70%,
      rgb(11 111 211 / 8%) 0 1px,
      transparent 1.4px
    );
  background-size:
    180px 180px,
    240px 240px,
    200px 200px;
  mix-blend-mode: soft-light;
  opacity: 0.65;
}

.auth-glow {
  position: absolute;
  pointer-events: none;
  border-radius: 9999px;
}

.auth-glow-primary {
  top: 4rem;
  left: 50%;
  width: 26rem;
  height: 26rem;
  background: radial-gradient(
    circle,
    rgb(87 150 255 / 24%) 0%,
    rgb(87 150 255 / 0%) 68%
  );
  transform: translateX(-50%);
}

.auth-glow-secondary {
  top: 46%;
  left: 14%;
  width: 20rem;
  height: 20rem;
  background: radial-gradient(
    circle,
    rgb(36 189 211 / 18%) 0%,
    rgb(36 189 211 / 0%) 72%
  );
}

.auth-glow-tertiary {
  right: 10%;
  bottom: 8%;
  width: 22rem;
  height: 22rem;
  background: radial-gradient(
    circle,
    rgb(66 116 255 / 14%) 0%,
    rgb(66 116 255 / 0%) 74%
  );
}

.auth-brand-chip {
  min-height: 3rem;
  padding: 0.45rem 0.95rem;
  background: rgb(255 255 255 / 72%);
  border: 1px solid rgb(255 255 255 / 84%);
  border-radius: 9999px;
  box-shadow: 0 20px 44px -32px rgb(11 59 132 / 26%);
  backdrop-filter: blur(12px);
}

.auth-brand-name {
  font-size: 0.95rem;
  font-weight: 600;
  letter-spacing: -0.01em;
}

.auth-page-title {
  max-width: 16ch;
  margin: 0 auto;
  font-size: clamp(2.1rem, 4vw, 3.7rem);
  font-weight: 700;
  line-height: 1.05;
  letter-spacing: -0.04em;
}

.auth-stage-switcher {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 0.7rem;
  align-items: center;
  justify-content: center;
  margin-top: 1rem;
}

.auth-stage-switcher-label {
  font-size: 0.98rem;
  line-height: 1.6;
}

.auth-stage-pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 6.5rem;
  padding: 0.55rem 1rem;
  font-size: 0.95rem;
  font-weight: 600;
  color: hsl(var(--nav-item-active-foreground));
  background: rgb(255 255 255 / 74%);
  border: 1px solid rgb(255 255 255 / 90%);
  border-radius: 9999px;
  box-shadow: 0 18px 34px -28px rgb(14 61 132 / 30%);
  backdrop-filter: blur(10px);
}

.auth-stage-pill-text {
  display: inline-flex;
  justify-content: center;
  min-width: 4em;
}

.auth-pill-enter-active,
.auth-pill-leave-active {
  transition:
    opacity 180ms ease,
    transform 180ms ease;
}

.auth-pill-enter-from {
  opacity: 0;
  transform: translateY(8px);
}

.auth-pill-leave-to {
  opacity: 0;
  transform: translateY(-8px);
}

.auth-window-host {
  position: relative;
  z-index: 1;
}

.dark.auth-shell {
  background:
    radial-gradient(
      circle at top,
      rgb(35 66 114 / 32%),
      rgb(15 22 35 / 0%) 40%
    ),
    linear-gradient(180deg, #06101b 0%, #08111d 52%, #09131f 100%);

  .auth-shell-grid {
    background-image:
      linear-gradient(rgb(118 160 241 / 8%) 1px, transparent 1px),
      linear-gradient(90deg, rgb(118 160 241 / 8%) 1px, transparent 1px);
    opacity: 0.36;
  }

  .auth-shell-noise {
    opacity: 0.38;
  }

  .auth-brand-chip {
    background: rgb(11 19 31 / 68%);
    border-color: rgb(138 174 255 / 18%);
    box-shadow: 0 24px 48px -34px rgb(0 0 0 / 52%);
  }

  .auth-stage-switcher-label {
    color: rgb(195 206 230 / 80%);
  }

  .auth-stage-pill {
    color: rgb(144 196 255 / 92%);
    background: rgb(11 19 31 / 70%);
    border-color: rgb(138 174 255 / 18%);
    box-shadow: 0 18px 34px -28px rgb(0 0 0 / 46%);
  }

  .auth-glow-primary {
    background: radial-gradient(
      circle,
      rgb(70 120 255 / 26%) 0%,
      rgb(70 120 255 / 0%) 70%
    );
  }

  .auth-glow-secondary {
    background: radial-gradient(
      circle,
      rgb(41 170 201 / 18%) 0%,
      rgb(41 170 201 / 0%) 72%
    );
  }

  .auth-glow-tertiary {
    background: radial-gradient(
      circle,
      rgb(95 128 255 / 16%) 0%,
      rgb(95 128 255 / 0%) 74%
    );
  }
}

@media (max-width: 768px) {
  .auth-page-title {
    max-width: 14ch;
  }
}

@media (max-width: 640px) {
  .auth-stage {
    padding-top: 6.75rem;
  }

  .auth-stage-copy {
    text-align: left;
  }

  .auth-page-title {
    max-width: none;
    margin-right: 0;
    margin-left: 0;
  }

  .auth-stage-switcher {
    justify-content: flex-start;
  }
}
</style>
