import { useEffect, useRef, useState, useSyncExternalStore } from 'react';
import { toast } from 'sonner';

export type RecorderStatus = 'idle' | 'recording' | 'paused';

// Module-level singleton so the recording state can be shared between
// the CaptureTab (inside the 3D HUD) and a floating indicator.
type State = { status: RecorderStatus; elapsedMs: number };
let state: State = { status: 'idle', elapsedMs: 0 };
const listeners = new Set<() => void>();
function setState(next: Partial<State>) {
  state = { ...state, ...next };
  listeners.forEach((l) => l());
}
function subscribe(l: () => void) { listeners.add(l); return () => { listeners.delete(l); }; }
function getSnapshot() { return state; }

let recorder: MediaRecorder | null = null;
let chunks: Blob[] = [];
let startedAt = 0;
let accumulatedMs = 0;
let pausedAt = 0;
let tickTimer: number | null = null;

function pickMimeType(): string | undefined {
  const candidates = [
    'video/webm;codecs=vp9,opus',
    'video/webm;codecs=vp9',
    'video/webm;codecs=vp8',
    'video/webm',
    'video/mp4',
  ];
  for (const t of candidates) {
    if (typeof MediaRecorder !== 'undefined' && MediaRecorder.isTypeSupported?.(t)) return t;
  }
  return undefined;
}

function startTick() {
  if (tickTimer != null) return;
  tickTimer = window.setInterval(() => {
    if (state.status === 'recording') {
      setState({ elapsedMs: accumulatedMs + (performance.now() - startedAt) });
    }
  }, 250);
}
function stopTick() {
  if (tickTimer != null) { clearInterval(tickTimer); tickTimer = null; }
}

function getCanvas(): HTMLCanvasElement | null {
  return document.querySelector('canvas');
}

export function startRecording() {
  if (state.status !== 'idle') return;
  const canvas = getCanvas();
  if (!canvas) { toast.error('Canvas não encontrado'); return; }
  const stream = (canvas as any).captureStream?.(30) as MediaStream | undefined;
  if (!stream) { toast.error('captureStream não suportado neste browser'); return; }
  const mimeType = pickMimeType();
  try {
    recorder = new MediaRecorder(stream, mimeType ? { mimeType, videoBitsPerSecond: 8_000_000 } : undefined);
  } catch (e) {
    console.error(e);
    toast.error('MediaRecorder falhou ao iniciar');
    return;
  }
  chunks = [];
  recorder.ondataavailable = (e) => { if (e.data && e.data.size > 0) chunks.push(e.data); };
  recorder.onstop = () => {
    const type = recorder?.mimeType || 'video/webm';
    const blob = new Blob(chunks, { type });
    const ext = type.includes('mp4') ? 'mp4' : 'webm';
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = `steelxr-AR-${new Date().toISOString().replace(/[:.]/g, '-')}.${ext}`;
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
    setTimeout(() => URL.revokeObjectURL(url), 5000);
    toast.success(`Vídeo salvo (${(blob.size / 1_000_000).toFixed(1)} MB)`);
    recorder = null;
    chunks = [];
    accumulatedMs = 0;
    stopTick();
    setState({ status: 'idle', elapsedMs: 0 });
  };
  recorder.start(1000);
  startedAt = performance.now();
  accumulatedMs = 0;
  setState({ status: 'recording', elapsedMs: 0 });
  startTick();
  toast.success('Gravação iniciada');
}

export function pauseRecording() {
  if (!recorder || state.status !== 'recording') return;
  recorder.pause();
  accumulatedMs += performance.now() - startedAt;
  pausedAt = performance.now();
  setState({ status: 'paused', elapsedMs: accumulatedMs });
}

export function resumeRecording() {
  if (!recorder || state.status !== 'paused') return;
  recorder.resume();
  startedAt = performance.now();
  setState({ status: 'recording' });
}

export function stopRecording() {
  if (!recorder) return;
  try { recorder.stop(); } catch (e) { console.error(e); }
}

export function captureScreenshot(): string | null {
  const canvas = getCanvas();
  if (!canvas) { toast.error('Canvas não encontrado'); return null; }
  try {
    const dataUrl = canvas.toDataURL('image/png');
    // Trigger download
    const a = document.createElement('a');
    a.href = dataUrl;
    a.download = `steelxr-AR-${new Date().toISOString().replace(/[:.]/g, '-')}.png`;
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
    toast.success('Foto capturada');
    return dataUrl;
  } catch (e) {
    console.error(e);
    toast.error('Falha ao capturar foto');
    return null;
  }
}

export function useCanvasRecorder() {
  return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
}

export function formatElapsed(ms: number): string {
  const s = Math.floor(ms / 1000);
  const m = Math.floor(s / 60);
  const ss = (s % 60).toString().padStart(2, '0');
  const mm = m.toString().padStart(2, '0');
  return `${mm}:${ss}`;
}
