<template lang="pug">
  v-app.zen-app.overflow-hidden
    v-navigation-drawer(
      v-if="store.token || viewState === 'zooming'"
      v-model="drawer"
      temporary
      location="right"
      color="#1e1e24"
      class="border-none"
      width="280"
    )
      .d-flex.flex-column.h-100.pa-4
        .d-flex.align-center.mb-6.px-2
          img.mr-3(:src="logo" height="32" width="32" alt="Logo")
          span.text-h6.font-weight-bold {{ $t('nav.menu') }}

        v-list.pa-0(nav bg-color="transparent")
          v-list-item.mb-2(
            to="/"
            rounded="lg"
            :active="$route.path === '/'"
          )
            template(v-slot:prepend)
              v-icon(color="#00cec9" icon="mdi-view-dashboard")
            v-list-item-title.font-weight-bold {{ $t('nav.dashboard') }}

          v-list-item.mb-2(
            to="/collection"
            rounded="lg"
            :active="$route.path === '/collection'"
          )
            template(v-slot:prepend)
              v-icon(color="#00cec9" icon="mdi-bookshelf")
            v-list-item-title.font-weight-bold {{ $t('nav.collection') }}

        v-divider.my-4.border-subtle

        .d-flex.flex-column.gap-2
          v-btn.justify-start.px-4(
            variant="text"
            block
            color="grey-lighten-1"
            @click="showSettings = true; drawer = false"
          )
            v-icon(start icon="mdi-cog")
            | {{ $t('nav.settings') }}

          v-btn.justify-start.px-4(
            variant="text"
            block
            color="grey-lighten-1"
            :loading="syncing"
            @click="manualSync"
          )
            v-icon(start icon="mdi-sync")
            | {{ $t('nav.sync') }}

          v-btn.justify-start.px-4.text-red-lighten-2(
            variant="text"
            block
            @click="handleLogout"
          )
            v-icon(start icon="mdi-logout")
            | {{ $t('nav.logout') }}
    .parallax-bg(
      :style="parallaxStyle"
      :class="{ 'zooming': viewState === 'zooming' }"
    )
      .bg-gradient
      .bg-grid

      .kanji-layer
        span.bg-kanji(
          v-for="(k, i) in backgroundKanjis"
          :key="i"
          :style="k.style"
        ) {{ k.char }}

      .orb.orb-1(:class="{ 'zooming': viewState === 'zooming' }")
      .orb.orb-2(:class="{ 'zooming': viewState === 'zooming' }")
      .orb.orb-3(:class="{ 'zooming': viewState === 'zooming' }")

    .app-content-wrapper(
      v-if="store.token || viewState === 'zooming'"
      :class="{ 'app-entering': viewState === 'zooming', 'app-visible': viewState === 'app' }"
    )

      v-app-bar.px-2.app-bar-blur.safe-area-header(
        flat
        color="rgba(30, 30, 36, 0.8)"
        border="b"
      )
        v-app-bar-title.font-weight-bold.text-h6(style="min-width: fit-content;")
          .d-flex.align-center.cursor-pointer.logo-hover(@click="$router.push('/')")
            img(:src="logo" height="32" width="32" alt="Zen Kanji Logo")
            span.ml-3.tracking-tight Zen Kanji

        v-spacer

        template(v-if="store.token")
          .d-none.d-md-flex.align-center
            v-btn.mx-1(
              to="/"
              variant="text"
              :color="$route.path === '/' ? '#00cec9' : 'grey'"
            ) {{ $t('nav.dashboard') }}

            v-btn.mx-1(
              to="/collection"
              variant="text"
              :color="$route.path === '/collection' ? '#00cec9' : 'grey'"
            ) {{ $t('nav.collection') }}

            v-divider.mx-2.my-auto(vertical length="20" color="grey-darken-2")

            v-tooltip(:text="$t('nav.settings')" location="bottom")
              template(v-slot:activator="{ props }")
                v-btn(
                  v-bind="props"
                  icon="mdi-cog"
                  variant="text"
                  color="grey-lighten-1"
                  @click="showSettings = true"
                )

            v-tooltip(:text="$t('nav.sync')" location="bottom")
              template(v-slot:activator="{ props }")
                v-btn(
                  v-bind="props"
                  icon="mdi-sync"
                  variant="text"
                  :loading="syncing"
                  color="grey-lighten-1"
                  @click="manualSync"
                )

            v-tooltip(:text="$t('nav.logout')" location="bottom")
              template(v-slot:activator="{ props }")
                v-btn(
                  v-bind="props"
                  icon="mdi-logout"
                  variant="text"
                  color="grey-darken-1"
                  @click="handleLogout"
                )

          .d-flex.d-md-none
            v-btn(
              icon="mdi-menu"
              variant="text"
              color="grey-lighten-1"
              @click="drawer = !drawer"
            )

      v-main.fill-height
        router-view(v-slot="{ Component }")
          transition(name="page" mode="out-in")
            component(:is="Component")

    .login-overlay(
      v-if="!store.token || viewState === 'zooming' || viewState === 'authenticating'"
      :class="{ 'zooming': viewState === 'zooming' }"
    )
      v-card.login-card.pa-6.rounded-lg.elevation-10.text-center.border-subtle(
        color="#1e1e24"
        width="100%"
        max-width="400"
      )
        .login-content
          img.mb-4(:src="logo" height="64" width="64")

          h1.text-h5.font-weight-bold.mb-2 {{ $t('hero.welcome') }}
          p.text-grey-lighten-1.text-body-2.mb-6 {{ $t('login.instruction') }}

          v-text-field.mb-2(
            v-model="inputKey"
            :placeholder="$t('login.placeholder')"
            variant="solo-filled"
            bg-color="#2f3542"
            color="white"
            hide-details
            density="comfortable"
            @keyup.enter="triggerLogin"
            :disabled="viewState === 'authenticating' || viewState === 'zooming'"
          )

          v-alert.mb-4.text-left.text-caption(
            v-if="errorMsg"
            type="error"
            density="compact"
            variant="tonal"
          ) {{ errorMsg }}

          v-btn.text-black.font-weight-bold.mt-4.login-btn(
            block
            color="#00cec9"
            height="44"
            :loading="viewState === 'authenticating'"
            @click="triggerLogin"
          ) {{ $t('login.button') }}

    v-dialog(v-model="showSettings" max-width="340")
      v-card.rounded-xl.pa-4.border-subtle(color="#1e1e24")
        v-card-title.text-center.font-weight-bold {{ $t('settings.title') }}

        v-card-text.pt-4
          .text-caption.text-grey.mb-2 {{ $t('settings.batchSize') }}
          v-slider(
            v-model="tempBatchSize"
            :min="5"
            :max="100"
            :step="5"
            thumb-label
            color="#00cec9"
            track-color="grey-darken-3"
          )
          .text-center.text-h5.font-weight-bold.text-teal-accent-3.mb-6
            | {{ tempBatchSize }} {{ $t('settings.items') }}

          .text-caption.text-grey.mb-2 {{ $t('settings.drawingTolerance') }}
          v-slider(
            v-model="tempDrawingAccuracy"
            :min="1"
            :max="20"
            :step="1"
            thumb-label
            color="#00cec9"
            track-color="grey-darken-3"
          )
          .d-flex.justify-space-between.text-caption.text-grey-lighten-1.mb-6.px-1
            span {{ $t('settings.strict') }} (5)
            span.font-weight-bold.text-body-1(color="#00cec9") {{ tempDrawingAccuracy }}
            span {{ $t('settings.loose') }} (20)

          .text-caption.text-grey.mb-2 {{ $t('settings.language') }}

          .lang-switch-wrapper.border-subtle.mb-2
            .lang-glider(:style="{ transform: `translateX(${localeIndex * 100}%)` }")
            button.lang-btn(
              v-for="l in availableLocales"
              :key="l"
              :class="{ 'active': tempLocale === l }"
              @click="tempLocale = l"
            ) {{ l.toUpperCase() }}

        v-card-actions.mt-2
          v-btn.text-white(
            block
            color="#2f3542"
            @click="saveSettings"
          ) {{ $t('settings.save') }}

    v-dialog(v-model="showLogoutDialog" max-width="320")
      v-card.rounded-xl.pa-4.border-subtle(color="#1e1e24")
        .d-flex.flex-column.align-center.text-center.pt-2
          v-avatar.mb-3(color="red-darken-4" size="48")
            v-icon(icon="mdi-logout" size="24" color="red-lighten-1")

          h3.text-h6.font-weight-bold.mb-2 {{ $t('nav.logout') }}?

          p.text-body-2.text-grey-lighten-1.px-2.mb-4
            | {{ $t('alerts.logoutConfirm') }}

        v-card-actions.d-flex.gap-2.pa-0.mt-2
          v-btn.flex-grow-1.text-capitalize(
            variant="tonal"
            color="grey"
            height="40"
            @click="showLogoutDialog = false"
          ) {{ $t('common.cancel') }}

          v-btn.flex-grow-1.text-capitalize(
            color="red-accent-2"
            variant="flat"
            height="40"
            @click="confirmLogout"
          ) {{ $t('nav.logout') }}

    v-snackbar(v-model="snackbar.show" :color="snackbar.color" timeout="3000")
      | {{ snackbar.text }}
      template(v-slot:actions)
        v-btn(variant="text" @click="snackbar.show = false") {{ $t('common.close') }}
</template>

<script setup>
/* eslint-disable no-unused-vars */
import {
  ref, watch, onMounted, computed, onUnmounted,
} from 'vue';
import { useI18n } from 'vue-i18n';
import { App as CapacitorApp } from '@capacitor/app';
import { useAppStore } from '@/stores/appStore';
import { checkForUpdates } from '@/utils/autoUpdate';
import logo from '@/assets/icon.svg';

const drawer = ref(false);
const { locale, t } = useI18n();
const store = useAppStore();

const viewState = ref('login');
const mousePos = ref({ x: 0, y: 0 });

const inputKey = ref('');
const syncing = ref(false);
const errorMsg = ref('');
const showSettings = ref(false);
const showLogoutDialog = ref(false);
const snackbar = ref({ show: false, text: '', color: 'success' });

const tempBatchSize = ref(store.batchSize);
const tempDrawingAccuracy = ref(store.drawingAccuracy);

const availableLocales = ['en', 'de', 'ja'];
const tempLocale = ref(locale.value);
const localeIndex = computed(() => availableLocales.indexOf(tempLocale.value));

const backgroundKanjis = [
  {
    char: '禅',
    style: {
      top: '15%', left: '10%', fontSize: '8rem', opacity: 0.03,
    },
  },
  {
    char: '空',
    style: {
      top: '60%', left: '85%', fontSize: '10rem', opacity: 0.03,
    },
  },
  {
    char: '無',
    style: {
      top: '30%', left: '60%', fontSize: '12rem', opacity: 0.02,
    },
  },
  {
    char: '心',
    style: {
      top: '80%', left: '20%', fontSize: '6rem', opacity: 0.04,
    },
  },
  {
    char: '道',
    style: {
      top: '10%', left: '70%', fontSize: '5rem', opacity: 0.05,
    },
  },
  {
    char: '学',
    style: {
      top: '50%', left: '5%', fontSize: '4rem', opacity: 0.04,
    },
  },
  {
    char: '夢',
    style: {
      top: '90%', left: '60%', fontSize: '7rem', opacity: 0.03,
    },
  },
  {
    char: '力',
    style: {
      top: '25%', left: '35%', fontSize: '3rem', opacity: 0.05,
    },
  },
  {
    char: '月',
    style: {
      top: '75%', left: '90%', fontSize: '4rem', opacity: 0.04,
    },
  },
  {
    char: '水',
    style: {
      top: '40%', left: '80%', fontSize: '5rem', opacity: 0.03,
    },
  },
  {
    char: '火',
    style: {
      top: '70%', left: '50%', fontSize: '9rem', opacity: 0.02,
    },
  },
];

const handleMouseMove = (e) => {
  mousePos.value = {
    x: (e.clientX / window.innerWidth) * 2 - 1,
    y: (e.clientY / window.innerHeight) * 2 - 1,
  };
};

onMounted(() => {
  CapacitorApp.addListener('appStateChange', ({ isActive }) => {
    if (isActive) checkForUpdates();
  });
  if (store.token) {
    viewState.value = 'app';
    store.fetchStats();
  } else {
    viewState.value = 'login';
  }
  window.addEventListener('mousemove', handleMouseMove);
});

onUnmounted(() => {
  window.removeEventListener('mousemove', handleMouseMove);
});

const parallaxStyle = computed(() => {
  if (viewState.value === 'app') return {};
  const x = mousePos.value.x * -20;
  const y = mousePos.value.y * -20;
  return {
    transform: `translate(${x}px, ${y}px) scale(1.1)`,
  };
});

watch(showSettings, (isOpen) => {
  if (isOpen) {
    tempBatchSize.value = store.batchSize;
    tempDrawingAccuracy.value = store.drawingAccuracy;
    tempLocale.value = locale.value;
  }
});

async function manualSync() {
  syncing.value = true;
  try {
    const result = await store.sync();
    snackbar.value = { show: true, text: t('alerts.syncSuccess', { count: result.count }), color: 'success' };
    await store.fetchQueue();
    await store.fetchStats();
    await store.fetchCollection();
  } catch (e) {
    console.error(e);
    snackbar.value = { show: true, text: t('alerts.syncFailed'), color: 'error' };
  } finally {
    syncing.value = false;
  }
}

async function triggerLogin() {
  if (!inputKey.value) return;
  viewState.value = 'authenticating';
  errorMsg.value = '';

  try {
    const result = await store.login(inputKey.value.trim());

    setTimeout(() => {
      viewState.value = 'zooming';
      setTimeout(() => {
        viewState.value = 'app';
        if (result.user && !result.user.lastSync) {
          manualSync();
        }
      }, 1000);
    }, 800);
  } catch (e) {
    console.error(e);
    errorMsg.value = e.message || t('login.failed');
    viewState.value = 'login';
  }
}

function saveSettings() {
  showSettings.value = false;

  setTimeout(() => {
    if (locale.value !== tempLocale.value) {
      locale.value = tempLocale.value;
      localStorage.setItem('zen_locale', locale.value);
    }

    store.saveSettings({
      batchSize: tempBatchSize.value,
      drawingAccuracy: tempDrawingAccuracy.value,
    });

    store.fetchQueue();
  }, 300);
}

function handleLogout() {
  showLogoutDialog.value = true;
  drawer.value = false;
}

function confirmLogout() {
  store.logout();
  inputKey.value = '';
  showLogoutDialog.value = false;
  viewState.value = 'login';
}
</script>

<style lang="scss">
.zen-app {
  position: relative;
  background-color: #121212 !important;
}

.parallax-bg {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  z-index: 0;
  transition: transform 0.2s ease-out;
  background: radial-gradient(circle at 50% 50%, #1a1a20 0%, #0a0a0c 100%);
  overflow: hidden;

  &.zooming {
    transition: transform 1.2s cubic-bezier(0.7, 0, 0.3, 1);
  }

  .bg-grid {
    position: absolute;
    inset: 0;
    background-image: radial-gradient(rgba(0, 206, 201, 0.15) 1px, transparent 1px);
    background-size: 40px 40px;
    opacity: 0.3;
  }

  .kanji-layer {
    position: absolute;
    inset: 0;
    pointer-events: none;
    overflow: hidden;
  }

  .bg-kanji {
    position: absolute;
    color: rgba(255, 255, 255, 0.8);
    font-weight: 900;
    font-family: "Noto Serif JP", serif;
    user-select: none;
    pointer-events: none;
    z-index: 1;
  }

  .orb {
    position: absolute;
    border-radius: 50%;
    filter: blur(80px);
    mix-blend-mode: screen;
    opacity: 0.6;
    animation: blob 10s infinite alternate;
    transition: all 1.2s ease-in-out;
    z-index: 0;

    &.zooming {
      transform: scale(5);
      opacity: 0;
    }
  }

  .orb-1 {
    top: 20%;
    left: 20%;
    width: 400px;
    height: 400px;
    background: rgba(0, 206, 201, 0.15);
  }

  .orb-2 {
    top: 30%;
    right: 20%;
    width: 350px;
    height: 350px;
    background: rgba(162, 155, 254, 0.15);
    animation-delay: 2s;
  }

  .orb-3 {
    bottom: 10%;
    left: 30%;
    width: 300px;
    height: 300px;
    background: rgba(30, 144, 255, 0.1);
    animation-delay: 4s;
  }
}

@keyframes blob {
  0% {
    transform: translate(0, 0) scale(1);
  }

  50% {
    transform: translate(30px, -50px) scale(1.1);
  }

  100% {
    transform: translate(-20px, 20px) scale(0.9);
  }
}

.login-overlay {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 1.2s cubic-bezier(0.7, 0, 0.3, 1);
  transform-origin: center center;

  &.zooming {
    transform: scale(15);
    opacity: 0;
    pointer-events: none;
  }

  .login-card {
    position: relative;
    background: rgba(30, 30, 36, 0.6) !important;
    backdrop-filter: blur(20px);
    border: 1px solid rgba(255, 255, 255, 0.1);
    box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5);
    transition: transform 0.5s ease;

    &:hover {
      transform: scale(1.01);
    }
  }
}

.app-content-wrapper {
  position: relative;
  z-index: 10;
  width: 100%;
  height: 100%;
  opacity: 0;
  transform: scale(0.95);
  filter: blur(10px);
  transition: all 1.2s cubic-bezier(0.4, 0, 0.2, 1);
  pointer-events: none;

  &.app-entering {
    opacity: 0;
  }

  &.app-visible {
    opacity: 1;
    transform: scale(1);
    filter: none;
    pointer-events: auto;
  }
}
</style>
