<script setup lang="ts">
import { computed } from 'vue';

import { buildClockState } from '@/lib/clock';
import type { DashboardMode } from '@/lib/dashboard-mode';

const SIMPLE_CLOCK_SIZE = 480;
// 5 分钟刻度的外沿需要和普通刻度落在同一圈上，
// 所以这里按统一 outer inset 重新计算大刻度中心距离。
const SIMPLE_HOUR_TICK_DISTANCE = 194.59034156799316;
const SIMPLE_MINUTE_TICK_DISTANCE = 207.39662265777588;
const SIMPLE_HOUR_HAND_FRONT = 148.8;
const SIMPLE_HOUR_HAND_BACK = 67.2;
// 分针前端要求和分钟刻度外端严格对齐。
const SIMPLE_MINUTE_HAND_FRONT = 218.26450538635254;
const SIMPLE_MINUTE_HAND_BACK = 72;
const SIMPLE_MINUTE_HAND_THICKNESS = 9.6;

const props = withDefaults(
  defineProps<{
    date: Date;
    mode: DashboardMode;
    size?: number;
  }>(),
  {
    size: SIMPLE_CLOCK_SIZE,
  },
);

const clockState = computed(() => buildClockState(props.date));
const scale = computed(() => props.size / SIMPLE_CLOCK_SIZE);

// simple 主题的表盘不是图片，而是按 Figma 参数直接绘制。
const hourTicks = Array.from({ length: 12 }, (_, index) => index * 30);
const minuteTicks = Array.from({ length: 60 }, (_, index) => index).filter((index) => index % 5 !== 0);

const stageStyle = computed(() => ({
  width: `${props.size}px`,
  height: `${props.size}px`,
}));

function buildHourTickStyle(angle: number) {
  return {
    width: `${14.4 * scale.value}px`,
    height: `${47.34832763671875 * scale.value}px`,
    transform: `translate(-50%, -50%) rotate(${angle}deg) translateY(-${SIMPLE_HOUR_TICK_DISTANCE * scale.value}px)`,
  };
}

function buildMinuteTickStyle(index: number) {
  return {
    width: `${6.520815372467041 * scale.value}px`,
    height: `${21.73549461364746 * scale.value}px`,
    transform: `translate(-50%, -50%) rotate(${index * 6}deg) translateY(-${SIMPLE_MINUTE_TICK_DISTANCE * scale.value}px)`,
  };
}

const hourHandStyle = computed(() => ({
  width: `${14.4 * scale.value}px`,
  height: `${(SIMPLE_HOUR_HAND_FRONT + SIMPLE_HOUR_HAND_BACK) * scale.value}px`,
  transformOrigin: `50% ${SIMPLE_HOUR_HAND_BACK * scale.value}px`,
  transform: `translate(-50%, -${SIMPLE_HOUR_HAND_BACK * scale.value}px) rotate(${clockState.value.hourAngle}deg)`,
}));

const minuteHandStyle = computed(() => ({
  width: `${SIMPLE_MINUTE_HAND_THICKNESS * scale.value}px`,
  height: `${(SIMPLE_MINUTE_HAND_FRONT + SIMPLE_MINUTE_HAND_BACK) * scale.value}px`,
  transformOrigin: `50% ${SIMPLE_MINUTE_HAND_BACK * scale.value}px`,
  transform: `translate(-50%, -${SIMPLE_MINUTE_HAND_BACK * scale.value}px) rotate(${clockState.value.minuteAngle}deg)`,
}));
</script>

<template>
  <div class="simple-analog-clock" :style="stageStyle" data-clock-region="true">
    <template v-if="mode !== 'background'">
      <div class="simple-analog-clock__face-shadow" />
      <div class="simple-analog-clock__face" />

      <div
        v-for="angle in hourTicks"
        :key="`hour-${angle}`"
        class="simple-analog-clock__tick simple-analog-clock__tick--hour"
        :style="buildHourTickStyle(angle)"
      />

      <div
        v-for="index in minuteTicks"
        :key="`minute-${index}`"
        class="simple-analog-clock__tick simple-analog-clock__tick--minute"
        :style="buildMinuteTickStyle(index)"
      />

      <div class="simple-analog-clock__hand simple-analog-clock__hand--minute" :style="minuteHandStyle" />
      <div class="simple-analog-clock__hand simple-analog-clock__hand--hour" :style="hourHandStyle" />
      <div class="simple-analog-clock__center simple-analog-clock__center--bottom" />
      <div class="simple-analog-clock__center simple-analog-clock__center--top" />
    </template>
  </div>
</template>

<style scoped>
.simple-analog-clock {
  position: relative;
  flex: 0 0 auto;
}

.simple-analog-clock__face-shadow,
.simple-analog-clock__face {
  position: absolute;
  border-radius: 50%;
  background: #ffffff;
}

.simple-analog-clock__face-shadow {
  inset: -2.4px;
  box-shadow: 0 1.8px 5.4px rgba(0, 0, 0, 0.3);
}

.simple-analog-clock__face {
  inset: 0;
  border: 1.6px solid #1e1e1e;
}

.simple-analog-clock__tick {
  position: absolute;
  top: 50%;
  left: 50%;
  background: #1e1e1e;
}

.simple-analog-clock__hand {
  position: absolute;
  top: 50%;
  left: 50%;
  background: #000000;
}

.simple-analog-clock__hand--minute {
  box-shadow: 0 3.6px 10.8px rgba(0, 0, 0, 0.4);
}

.simple-analog-clock__hand--hour {
  box-shadow: 2.4px 2.4px 10.8px rgba(0, 0, 0, 0.4);
}

.simple-analog-clock__center {
  position: absolute;
  top: 50%;
  left: 50%;
  border-radius: 50%;
  transform: translate(-50%, -50%);
  background: #000000;
}

.simple-analog-clock__center--bottom {
  width: 4.8px;
  height: 4.8px;
}

.simple-analog-clock__center--top {
  width: 9.6px;
  height: 9.6px;
}
</style>
