<template>
  <transition name="session-timeout-fade">
    <div v-if="visible" class="session-timeout-prompt" role="status" aria-live="polite">
      <div class="timeout-icon" aria-hidden="true">
        <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
          <circle cx="12" cy="12" r="9"></circle>
          <path d="M12 7v5l3 2"></path>
        </svg>
      </div>
      <div class="timeout-copy">
        <strong>即将自动退出</strong>
        <span>{{ countdownText }} 后将退出登录，以保护项目数据。</span>
      </div>
      <div class="timeout-actions">
        <el-button size="small" @click="logoutNow">立即退出</el-button>
        <el-button size="small" type="primary" @click="continueSession">继续使用</el-button>
      </div>
      <div class="timeout-progress" aria-hidden="true">
        <span :style="{ width: progressWidth }"></span>
      </div>
    </div>
  </transition>
</template>

<script setup lang="ts">
import { computed, onBeforeUnmount, ref, watch } from "vue";
import { useAuthStore } from "../store/auth";
import { useSessionStore } from "../store/session";
import {
  forceLogout,
  LOGOUT_REASON_MANUAL,
  markUserActive,
  TIMEOUT_WARNING_SECONDS,
} from "../session/sessionManager";

const auth = useAuthStore();
const session = useSessionStore();
const nowTs = ref(Date.now());
let timer: number | null = null;

const visible = computed(() => Boolean(auth.token && session.timeoutWarningVisible));

const countdownText = computed(() => {
  const remainSeconds = Math.max(0, Math.ceil((session.timeoutAt - nowTs.value) / 1000));
  return `${remainSeconds} 秒`;
});

const progressWidth = computed(() => {
  const remainSeconds = Math.max(0, Math.ceil((session.timeoutAt - nowTs.value) / 1000));
  const ratio = Math.min(1, remainSeconds / TIMEOUT_WARNING_SECONDS);
  return `${Math.round(ratio * 100)}%`;
});

const stopTimer = () => {
  if (!timer) return;
  window.clearInterval(timer);
  timer = null;
};

const startTimer = () => {
  stopTimer();
  nowTs.value = Date.now();
  timer = window.setInterval(() => {
    nowTs.value = Date.now();
  }, 1000);
};

const continueSession = () => {
  markUserActive();
};

const logoutNow = () => {
  forceLogout(LOGOUT_REASON_MANUAL);
};

watch(
  visible,
  (value) => {
    if (value) {
      startTimer();
      return;
    }
    stopTimer();
  },
  { immediate: true },
);

onBeforeUnmount(() => {
  stopTimer();
});
</script>

<style scoped>
.session-timeout-prompt {
  position: fixed;
  right: 24px;
  bottom: 24px;
  z-index: 2200;
  width: min(420px, calc(100vw - 32px));
  display: grid;
  grid-template-columns: 38px minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
  padding: 14px 16px;
  border-radius: 14px;
  border: 1px solid rgba(197, 139, 42, 0.24);
  background: rgba(255, 252, 246, 0.96);
  box-shadow: 0 18px 40px rgba(15, 23, 42, 0.14), inset 0 1px 0 rgba(255, 255, 255, 0.72);
  backdrop-filter: blur(16px);
  color: #3b2b12;
}

.timeout-progress {
  grid-column: 1 / -1;
  height: 3px;
  overflow: hidden;
  border-radius: 999px;
  background: rgba(197, 139, 42, 0.14);
}

.timeout-progress span {
  display: block;
  height: 100%;
  border-radius: inherit;
  background: linear-gradient(90deg, #d59a35, #f2b84f);
  box-shadow: 0 0 12px rgba(242, 184, 79, 0.36);
  transition: width 220ms ease;
}

.timeout-icon {
  width: 38px;
  height: 38px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 11px;
  color: var(--ctms-warning);
  background: #fff3dc;
  box-shadow: inset 0 0 0 1px rgba(197, 139, 42, 0.16);
}

.timeout-icon svg {
  width: 20px;
  height: 20px;
}

.timeout-copy {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.timeout-copy strong {
  font-size: 13px;
  line-height: 18px;
  font-weight: 800;
  color: #182235;
}

.timeout-copy span {
  font-size: 12px;
  line-height: 18px;
  font-weight: 600;
  color: #7a5a23;
}

.timeout-actions {
  display: inline-flex;
  gap: 8px;
  align-items: center;
}

.session-timeout-fade-enter-active,
.session-timeout-fade-leave-active {
  transition: opacity 160ms ease, transform 160ms ease;
}

.session-timeout-fade-enter-from,
.session-timeout-fade-leave-to {
  opacity: 0;
  transform: translateY(8px);
}

@media (max-width: 640px) {
  .session-timeout-prompt {
    left: 16px;
    right: 16px;
    bottom: 16px;
    width: auto;
    grid-template-columns: 34px minmax(0, 1fr);
  }

  .timeout-actions {
    grid-column: 1 / -1;
    justify-content: flex-end;
  }
}
</style>
