<script setup lang="ts">
import { computed, onBeforeUnmount, ref } from "vue";

import { heavenApi, type HeavenReading } from "../../shared/api/heaven";
import { useMarketStore } from "../../shared/stores/market";
import { useUiStore } from "../../shared/stores/ui";
import HexagramGraphic from "./HexagramGraphic.vue";
import { breathState } from "./heartTiming";

const props = defineProps<{ disabled: boolean }>();
const emit = defineEmits<{ interpret: [reading: HeavenReading] }>();
const market = useMarketStore();
const ui = useUiStore();
const stage = ref<"still" | "breath" | "cast" | "thought" | "result">("still");
const breathWord = ref("静");
const breathPhase = ref("prepare");
const incense = ref(0);
const values = ref<number[]>([]);
const coinFaces = ref<string[]>(["front", "back", "front"]);
const casting = ref(false);
const firstThought = ref(false);
const result = ref<any>(null);
const readingId = ref(0);
const muted = ref(false);
let breathTimer: ReturnType<typeof setInterval> | undefined;
let breathStarted = 0;
const positions = ["初爻", "二爻", "三爻", "四爻", "五爻", "上爻"];
const breathClass = computed(() => `is-${breathPhase.value}`);

function startBreath(): void {
  if (props.disabled) return;
  stage.value = "breath";
  breathStarted = performance.now();
  updateBreath();
  breathTimer = setInterval(updateBreath, 100);
}

function updateBreath(): void {
  const elapsed = performance.now() - breathStarted;
  const state = breathState(elapsed);
  incense.value = state.progress;
  breathWord.value = state.word;
  breathPhase.value = state.phase;
  if (state.phase === "complete") {
    clearBreath();
  }
}

function clearBreath(): void {
  if (breathTimer) clearInterval(breathTimer);
  breathTimer = undefined;
}

async function cast(): Promise<void> {
  if (casting.value || values.value.length >= 6 || props.disabled) return;
  casting.value = true;
  try {
    const response = await heavenApi.heartLine(market.selectedDate, values.value);
    coinFaces.value = response.faces;
    values.value = response.values;
    if (values.value.length === 6) stage.value = "thought";
  } catch (error) {
    ui.showToast(error instanceof Error ? error.message : "投掷未完成");
  } finally {
    window.setTimeout(() => { casting.value = false; }, 450);
  }
}

async function confirmThought(): Promise<void> {
  if (!firstThought.value || values.value.length !== 6) return;
  try {
    const response = await heavenApi.completeHeart(market.selectedDate, values.value);
    result.value = response.result;
    readingId.value = response.reading_id;
    stage.value = "result";
  } catch (error) {
    ui.showToast(error instanceof Error ? error.message : "成卦失败");
  }
}

function reading(): HeavenReading {
  return {
    id: readingId.value,
    mode: "heart",
    date: result.value.date,
    subject_key: "",
    result: result.value,
    interpretation: "",
    status: "pending",
    created_at: "",
  };
}

function reset(): void {
  clearBreath();
  stage.value = "still";
  breathWord.value = "静";
  breathPhase.value = "prepare";
  incense.value = 0;
  values.value = [];
  result.value = null;
  readingId.value = 0;
  firstThought.value = false;
}

onBeforeUnmount(clearBreath);
</script>

<template>
  <section class="heaven-panel heart-panel">
    <div class="heaven-heart-toolbar"><button class="btn btn-ghost btn-small" type="button" @click="muted = !muted">{{ muted ? '开启声音' : '静音' }}</button><button v-if="stage !== 'still'" class="btn btn-ghost btn-small" type="button" @click="reset">重新观心</button></div>
    <article v-if="stage === 'still'" class="card heart-still">
      <span class="heaven-heart-mark">心</span><h2>把所问之事留在心里</h2><p>不必输入，不必说明。先让念头安静下来，再看第一念如何浮现。</p><button class="btn btn-primary" type="button" :disabled="disabled" @click="startBreath">开始静心</button>
    </article>
    <article v-else-if="stage === 'breath'" class="card heart-breath">
      <div class="heart-ripple" :class="breathClass"><i /><i /><i /><strong>{{ breathWord }}</strong></div>
      <div class="heart-incense"><span>一炷香</span><div><i :style="{ width: `${incense * 100}%` }" /></div></div>
      <button v-if="breathPhase === 'complete'" class="btn btn-primary" type="button" @click="stage = 'cast'">静心完成，开始起卦</button>
    </article>
    <article v-else-if="stage === 'cast' || stage === 'thought'" class="heart-casting-layout">
      <section class="card heart-coins-card">
        <p class="muted">依次投掷六次，每次只得一爻</p>
        <div class="heart-coins" :class="{ 'is-casting': casting }"><span v-for="(face, index) in coinFaces" :key="index" class="heart-coin" :class="face"><i>{{ face === 'front' ? '乾' : '元' }}</i><small>{{ face === 'front' ? '通宝' : '坤仪' }}</small></span></div>
        <button v-if="stage === 'cast'" class="btn btn-primary" type="button" :disabled="casting" @click="cast">{{ casting ? '铜钱落定' : `投掷${positions[values.length]}` }}</button>
        <div v-else class="heart-thought"><label><input v-model="firstThought" type="checkbox" /> 我已记住此刻浮现的第一念</label><button class="btn btn-primary" type="button" :disabled="!firstThought" @click="confirmThought">确认第一念，完成起卦</button></div>
      </section>
      <section class="card heart-lines-card">
        <div v-for="(position, index) in positions" :key="position" class="heart-cast-line" :class="{ 'is-revealed': values[index] }"><span>{{ position }}</span><template v-if="values[index]"><span class="heaven-line-mini" :class="{ yin: values[index] % 2 === 0 }"><i /><i /></span><strong>{{ values[index] % 2 ? '阳爻' : '阴爻' }} · {{ values[index] }}</strong></template><em v-else>未得</em></div>
      </section>
    </article>
    <article v-else-if="result" class="card heart-result">
      <HexagramGraphic :hexagram="result.hexagram" />
      <div><span class="muted">卦辞</span><h2>{{ result.hexagram.name }}</h2><p>{{ result.hexagram.text }}</p><small>{{ result.notice }}</small></div>
      <button class="btn btn-primary" type="button" @click="emit('interpret', reading())">解卦</button>
    </article>
  </section>
</template>
