import type { SupabaseClient } from "@supabase/supabase-js";

/*
 * Aparelhos assistindo ao mesmo tempo com o mesmo login (Configurações dos
 * digitais). Cada navegador guarda um código sorteado; enquanto o vídeo toca,
 * ele dá sinal a cada 10 segundos. Passou do limite, o que começou primeiro
 * para sozinho, e quem quiser continuar nele toca em "Assistir aqui".
 */

const SINAL_VALE_MS = 60_000;

export function aparelhoValido(valor: unknown): string | null {
  return typeof valor === "string" && /^[A-Za-z0-9_-]{8,64}$/.test(valor) ? valor : null;
}

/** O sinal de quem está tocando. Devolve `true` quando este aparelho deve parar. */
export async function sinalDoAparelho(
  admin: SupabaseClient,
  params: {
    lojaId: string;
    clienteId: string;
    dispositivo: string;
    aulaId: string;
    limite: number;
    assumir: boolean;
    rede: string | null;
    navegador: string | null;
  }
): Promise<boolean> {
  const agora = new Date();
  const desde = new Date(agora.getTime() - SINAL_VALE_MS).toISOString();
  const { data: atual } = await admin
    .from("digital_playback_sessions")
    .select("id,ultimo_sinal_em")
    .eq("user_id", params.lojaId)
    .eq("client_id", params.clienteId)
    .eq("dispositivo", params.dispositivo)
    .maybeSingle();
  const linha = atual as { id: string; ultimo_sinal_em: string } | null;
  /* Começou agora (ou voltou depois de parado, ou pediu para assistir aqui): é o mais novo. */
  const comecou = !linha || linha.ultimo_sinal_em < desde || params.assumir;
  const dados = {
    lesson_id: params.aulaId,
    rede: params.rede?.slice(0, 64) ?? null,
    navegador: params.navegador?.slice(0, 300) ?? null,
    ultimo_sinal_em: agora.toISOString(),
    ...(comecou ? { iniciado_em: agora.toISOString() } : {}),
  };
  if (linha) {
    await admin.from("digital_playback_sessions").update(dados).eq("id", linha.id);
  } else {
    await admin.from("digital_playback_sessions").upsert(
      { user_id: params.lojaId, client_id: params.clienteId, dispositivo: params.dispositivo, ...dados },
      { onConflict: "user_id,client_id,dispositivo" }
    );
  }

  const { data: tocando } = await admin
    .from("digital_playback_sessions")
    .select("dispositivo")
    .eq("user_id", params.lojaId)
    .eq("client_id", params.clienteId)
    .gte("ultimo_sinal_em", desde)
    .order("iniciado_em", { ascending: false })
    .limit(20);
  const ordem = ((tocando ?? []) as Array<{ dispositivo: string }>).map((t) => t.dispositivo);
  const posicao = ordem.indexOf(params.dispositivo);
  return posicao >= Math.max(1, params.limite);
}

/** Pausou ou saiu da aula: o aparelho deixa de contar. */
export async function soltarAparelho(admin: SupabaseClient, params: { lojaId: string; clienteId: string; dispositivo: string }) {
  await admin
    .from("digital_playback_sessions")
    .update({ ultimo_sinal_em: new Date(0).toISOString() })
    .eq("user_id", params.lojaId)
    .eq("client_id", params.clienteId)
    .eq("dispositivo", params.dispositivo);
}
