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

const emit = defineEmits<{ recorded: [blob: Blob] }>();

const recording = ref(false);
const mediaRecorder = ref<MediaRecorder | null>(null);
const chunks = ref<Blob[]>([]);
const duration = ref(0);
let timer: ReturnType<typeof setInterval> | null = null;

async function start() {
  try {
    const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
    mediaRecorder.value = new MediaRecorder(stream);
    chunks.value = [];

    mediaRecorder.value.ondataavailable = (e) => chunks.value.push(e.data);
    mediaRecorder.value.onstop = () => {
      const blob = new Blob(chunks.value, { type: 'audio/webm' });
      emit('recorded', blob);
      stream.getTracks().forEach((t) => t.stop());
    };

    mediaRecorder.value.start();
    recording.value = true;
    duration.value = 0;
    timer = setInterval(() => duration.value++, 1000);
  } catch {
    // Microphone access denied
  }
}

function stop() {
  mediaRecorder.value?.stop();
  recording.value = false;
  if (timer) { clearInterval(timer); timer = null; }
}

function cancel() {
  if (mediaRecorder.value?.state === 'recording') {
    mediaRecorder.value.ondataavailable = null;
    mediaRecorder.value.onstop = null;
    mediaRecorder.value.stop();
  }
  recording.value = false;
  duration.value = 0;
  if (timer) { clearInterval(timer); timer = null; }
}

function formatTime(s: number) {
  const m = Math.floor(s / 60);
  const sec = s % 60;
  return `${m}:${sec.toString().padStart(2, '0')}`;
}
</script>

<template>
  <div class="voice-recorder">
    <div v-if="recording" class="voice-recorder__active">
      <span class="voice-recorder__dot" aria-hidden="true" />
      <span class="voice-recorder__time meta">{{ formatTime(duration) }}</span>
      <button class="voice-recorder__cancel" @click="cancel" aria-label="Отменить запись">
        <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" width="16" height="16">
          <path d="M18 6L6 18M6 6l12 12"/>
        </svg>
      </button>
      <button class="voice-recorder__stop" @click="stop" aria-label="Остановить запись">
        <svg viewBox="0 0 24 24" fill="currentColor" width="16" height="16">
          <rect x="3" y="3" width="18" height="18" rx="2"/>
        </svg>
      </button>
    </div>
    <button v-else class="voice-recorder__btn" @click="start" aria-label="Записать голосовое сообщение">
      <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" width="20" height="20">
        <path d="M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z"/>
        <path d="M19 10v2a7 7 0 0 1-14 0v-2M12 19v4M8 23h8"/>
      </svg>
    </button>
  </div>
</template>

<style scoped lang="scss">
.voice-recorder {
  &__btn {
    width: 40px;
    height: 40px;
    background: none;
    border: none;
    color: var(--color-muted);
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    transition: color var(--transition-fast);

    &:hover { color: var(--color-cream); }
  }

  &__active {
    display: flex;
    align-items: center;
    gap: 8px;
  }

  &__dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--color-signal);
    animation: pulse-signal 1s ease-in-out infinite;
  }

  &__time {
    font-variant-numeric: tabular-nums;
  }

  &__cancel,
  &__stop {
    width: 32px;
    height: 32px;
    border: none;
    border-radius: 50%;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: all var(--transition-fast);
  }

  &__cancel {
    background: var(--color-surface-2);
    color: var(--color-muted);
    &:hover { color: var(--color-cream); }
  }

  &__stop {
    background: var(--color-signal);
    color: white;
    &:hover { background: #a84e30; }
  }
}
</style>
