<script lang="ts">
  import { useQuery, useConvexClient } from "convex-svelte";
  import { api } from "@sgse-app/backend/convex/_generated/api";
  import type { Id } from "@sgse-app/backend/convex/_generated/dataModel";
  import { format } from "date-fns";
  import { ptBR } from "date-fns/locale";
  import { onMount, tick } from "svelte";
  import { authStore } from "$lib/stores/auth.svelte";

  interface Props {
    conversaId: Id<"conversas">;
  }

  let { conversaId }: Props = $props();

  const client = useConvexClient();
  const mensagens = useQuery(api.chat.obterMensagens, { conversaId, limit: 50 });
  const digitando = useQuery(api.chat.obterDigitando, { conversaId });

  let messagesContainer: HTMLDivElement;
  let shouldScrollToBottom = true;
  let lastMessageCount = 0;

  // Obter ID do usuário atual
  const usuarioAtualId = $derived(authStore.usuario?._id);

  // Auto-scroll para a última mensagem quando novas mensagens chegam
  $effect(() => {
    if (mensagens?.data && messagesContainer) {
      const currentCount = mensagens.data.length;
      const isNewMessage = currentCount > lastMessageCount;
      
      if (isNewMessage || shouldScrollToBottom) {
        // Usar requestAnimationFrame para garantir que o DOM foi atualizado
        requestAnimationFrame(() => {
          tick().then(() => {
            if (messagesContainer) {
              messagesContainer.scrollTop = messagesContainer.scrollHeight;
            }
          });
        });
      }
      
      lastMessageCount = currentCount;
    }
  });

  // Marcar como lida quando mensagens carregam
  $effect(() => {
    if (mensagens?.data && mensagens.data.length > 0 && usuarioAtualId) {
      const ultimaMensagem = mensagens.data[mensagens.data.length - 1];
      // Só marcar como lida se não for minha mensagem
      if (ultimaMensagem.remetente?._id !== usuarioAtualId) {
        client.mutation(api.chat.marcarComoLida, {
          conversaId,
          mensagemId: ultimaMensagem._id,
        });
      }
    }
  });

  function formatarDataMensagem(timestamp: number): string {
    try {
      return format(new Date(timestamp), "HH:mm", { locale: ptBR });
    } catch {
      return "";
    }
  }

  function formatarDiaMensagem(timestamp: number): string {
    try {
      return format(new Date(timestamp), "dd/MM/yyyy", { locale: ptBR });
    } catch {
      return "";
    }
  }

  interface Mensagem {
    _id: Id<"mensagens">;
    remetente?: {
      _id: Id<"usuarios">;
      nome: string;
    } | null;
    conteudo: string;
    tipo: "texto" | "arquivo" | "imagem";
    enviadaEm: number;
    editadaEm?: number;
    deletada?: boolean;
    agendadaPara?: number;
    respostaPara?: Id<"mensagens">;
    mensagemOriginal?: {
      _id: Id<"mensagens">;
      conteudo: string;
      remetente: {
        _id: Id<"usuarios">;
        nome: string;
      } | null;
      deletada: boolean;
    } | null;
    reagiuPor?: Array<{
      usuarioId: Id<"usuarios">;
      emoji: string;
    }>;
    arquivoUrl?: string | null;
    arquivoNome?: string;
    arquivoTamanho?: number;
    linkPreview?: {
      url: string;
      titulo?: string;
      descricao?: string;
      imagem?: string;
      site?: string;
    } | null;
  }

  function agruparMensagensPorDia(msgs: Mensagem[]): Record<string, Mensagem[]> {
    const grupos: Record<string, Mensagem[]> = {};
    for (const msg of msgs) {
      const dia = formatarDiaMensagem(msg.enviadaEm);
      if (!grupos[dia]) {
        grupos[dia] = [];
      }
      grupos[dia].push(msg);
    }
    return grupos;
  }

  function handleScroll(e: Event) {
    const target = e.target as HTMLDivElement;
    const isAtBottom =
      target.scrollHeight - target.scrollTop - target.clientHeight < 100;
    shouldScrollToBottom = isAtBottom;
  }

  async function handleReagir(mensagemId: Id<"mensagens">, emoji: string) {
    await client.mutation(api.chat.reagirMensagem, {
      mensagemId,
      emoji,
    });
  }

  function getEmojisReacao(mensagem: Mensagem): Array<{ emoji: string; count: number }> {
    if (!mensagem.reagiuPor || mensagem.reagiuPor.length === 0) return [];

    const emojiMap: Record<string, number> = {};
    for (const reacao of mensagem.reagiuPor) {
      emojiMap[reacao.emoji] = (emojiMap[reacao.emoji] || 0) + 1;
    }

    return Object.entries(emojiMap).map(([emoji, count]) => ({ emoji, count }));
  }

  let mensagemEditando: Mensagem | null = $state(null);
  let novoConteudoEditado = $state("");

  async function editarMensagem(mensagem: Mensagem) {
    mensagemEditando = mensagem;
    novoConteudoEditado = mensagem.conteudo;
  }

  async function salvarEdicao() {
    if (!mensagemEditando || !novoConteudoEditado.trim()) return;

    try {
      const resultado = await client.mutation(api.chat.editarMensagem, {
        mensagemId: mensagemEditando._id,
        novoConteudo: novoConteudoEditado.trim(),
      });

      if (resultado.sucesso) {
        mensagemEditando = null;
        novoConteudoEditado = "";
      } else {
        alert(resultado.erro || "Erro ao editar mensagem");
      }
    } catch (error) {
      console.error("Erro ao editar mensagem:", error);
      alert("Erro ao editar mensagem");
    }
  }

  function cancelarEdicao() {
    mensagemEditando = null;
    novoConteudoEditado = "";
  }

  async function deletarMensagem(mensagemId: Id<"mensagens">) {
    if (!confirm("Tem certeza que deseja deletar esta mensagem?")) {
      return;
    }

    try {
      await client.mutation(api.chat.deletarMensagem, {
        mensagemId,
      });
    } catch (error) {
      console.error("Erro ao deletar mensagem:", error);
      alert("Erro ao deletar mensagem");
    }
  }

  // Função para responder mensagem (será passada via props ou event)
  function responderMensagem(mensagem: Mensagem) {
    // Disparar evento customizado para o componente pai
    const event = new CustomEvent("responderMensagem", {
      detail: { mensagemId: mensagem._id },
    });
    window.dispatchEvent(event);
  }
</script>

<div
  class="h-full overflow-y-auto px-4 py-4 bg-base-100"
  bind:this={messagesContainer}
  onscroll={handleScroll}
>
  {#if mensagens?.data && mensagens.data.length > 0}
    {@const gruposPorDia = agruparMensagensPorDia(mensagens.data)}
    {#each Object.entries(gruposPorDia) as [dia, mensagensDia]}
      <!-- Separador de dia -->
      <div class="flex items-center justify-center my-4">
        <div class="px-3 py-1 rounded-full bg-base-300 text-base-content/70 text-xs">
          {dia}
        </div>
      </div>

      <!-- Mensagens do dia -->
      {#each mensagensDia as mensagem (mensagem._id)}
        {@const isMinha = mensagem.remetente?._id === usuarioAtualId}
        <div class={`flex mb-4 w-full ${isMinha ? "justify-end" : "justify-start"}`}>
          <div class={`flex flex-col max-w-[75%] ${isMinha ? "items-end" : "items-start"}`}>
            <!-- Nome do remetente (apenas se não for minha) -->
            {#if !isMinha}
              <p class="text-xs text-base-content/60 mb-1 px-3">
                {mensagem.remetente?.nome || "Usuário"}
              </p>
            {/if}

            <!-- Balão da mensagem -->
            <div
              class={`rounded-2xl px-4 py-2 ${
                isMinha
                  ? "bg-primary text-primary-content rounded-br-sm"
                  : "bg-base-200 text-base-content rounded-bl-sm"
              }`}
            >
              {#if mensagem.mensagemOriginal}
                <!-- Preview da mensagem respondida -->
                <div class="mb-2 pl-3 border-l-2 border-base-content/20 opacity-70">
                  <p class="text-xs font-medium">
                    {mensagem.mensagemOriginal.remetente?.nome || "Usuário"}
                  </p>
                  <p class="text-xs truncate">
                    {mensagem.mensagemOriginal.deletada 
                      ? "Mensagem deletada" 
                      : mensagem.mensagemOriginal.conteudo}
                  </p>
                </div>
              {/if}
              {#if mensagemEditando?._id === mensagem._id}
                <!-- Modo de edição -->
                <div class="space-y-2">
                  <textarea
                    bind:value={novoConteudoEditado}
                    class="w-full p-2 rounded-lg bg-base-100 text-base-content text-sm resize-none"
                    rows="3"
                    onkeydown={(e) => {
                      if (e.key === "Enter" && (e.ctrlKey || e.metaKey)) {
                        salvarEdicao();
                      } else if (e.key === "Escape") {
                        cancelarEdicao();
                      }
                    }}
                  ></textarea>
                  <div class="flex gap-2 justify-end">
                    <button
                      class="btn btn-xs btn-ghost"
                      onclick={cancelarEdicao}
                    >
                      Cancelar
                    </button>
                    <button
                      class="btn btn-xs btn-primary"
                      onclick={salvarEdicao}
                    >
                      Salvar
                    </button>
                  </div>
                </div>
              {:else if mensagem.deletada}
                <p class="text-sm italic opacity-70">Mensagem deletada</p>
              {:else if mensagem.tipo === "texto"}
                <div class="space-y-2">
                  <div class="flex items-start gap-2">
                    <p class="text-sm whitespace-pre-wrap break-words flex-1">{mensagem.conteudo}</p>
                    {#if mensagem.editadaEm}
                      <span class="text-xs opacity-50 italic" title="Editado">(editado)</span>
                    {/if}
                  </div>
                  
                  <!-- Preview de link -->
                  {#if mensagem.linkPreview}
                    <a
                      href={mensagem.linkPreview.url}
                      target="_blank"
                      rel="noopener noreferrer"
                      class="block border border-base-300 rounded-lg overflow-hidden hover:border-primary transition-colors"
                    >
                      {#if mensagem.linkPreview.imagem}
                        <img
                          src={mensagem.linkPreview.imagem}
                          alt={mensagem.linkPreview.titulo || "Preview"}
                          class="w-full h-48 object-cover"
                          onerror={(e) => {
                            (e.target as HTMLImageElement).style.display = "none";
                          }}
                        />
                      {/if}
                      <div class="p-3 bg-base-200">
                        {#if mensagem.linkPreview.site}
                          <p class="text-xs text-base-content/50 mb-1">{mensagem.linkPreview.site}</p>
                        {/if}
                        {#if mensagem.linkPreview.titulo}
                          <p class="text-sm font-medium text-base-content mb-1">{mensagem.linkPreview.titulo}</p>
                        {/if}
                        {#if mensagem.linkPreview.descricao}
                          <p class="text-xs text-base-content/70 line-clamp-2">{mensagem.linkPreview.descricao}</p>
                        {/if}
                      </div>
                    </a>
                  {/if}
                </div>
              {:else if mensagem.tipo === "imagem"}
                <div class="mb-2">
                  <img
                    src={mensagem.arquivoUrl}
                    alt={mensagem.arquivoNome}
                    class="max-w-full rounded-lg"
                  />
                </div>
                {#if mensagem.conteudo}
                  <p class="text-sm whitespace-pre-wrap break-words">{mensagem.conteudo}</p>
                {/if}
              {:else if mensagem.tipo === "arquivo"}
                <a
                  href={mensagem.arquivoUrl}
                  target="_blank"
                  rel="noopener noreferrer"
                  class="flex items-center gap-2 hover:opacity-80"
                >
                  <svg
                    xmlns="http://www.w3.org/2000/svg"
                    fill="none"
                    viewBox="0 0 24 24"
                    stroke-width="1.5"
                    stroke="currentColor"
                    class="w-5 h-5"
                  >
                    <path
                      stroke-linecap="round"
                      stroke-linejoin="round"
                      d="M19.5 14.25v-2.625a3.375 3.375 0 0 0-3.375-3.375h-1.5A1.125 1.125 0 0 1 13.5 7.125v-1.5a3.375 3.375 0 0 0-3.375-3.375H8.25m2.25 0H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 0 0-9-9Z"
                    />
                  </svg>
                  <div class="text-sm">
                    <p class="font-medium">{mensagem.arquivoNome}</p>
                    {#if mensagem.arquivoTamanho}
                      <p class="text-xs opacity-70">
                        {(mensagem.arquivoTamanho / 1024 / 1024).toFixed(2)} MB
                      </p>
                    {/if}
                  </div>
                </a>
              {/if}

              <!-- Reações -->
              {#if !mensagem.deletada && getEmojisReacao(mensagem).length > 0}
                <div class="flex items-center gap-1 mt-2">
                  {#each getEmojisReacao(mensagem) as reacao}
                    <button
                      type="button"
                      class="text-xs px-2 py-0.5 rounded-full bg-base-300/50 hover:bg-base-300"
                      onclick={() => handleReagir(mensagem._id, reacao.emoji)}
                    >
                      {reacao.emoji} {reacao.count}
                    </button>
                  {/each}
                </div>
              {/if}

              <!-- Botão de responder -->
              {#if !mensagem.deletada}
                <button
                  class="text-xs text-base-content/50 hover:text-primary transition-colors mt-1"
                  onclick={() => responderMensagem(mensagem)}
                  title="Responder"
                >
                  ↪️ Responder
                </button>
              {/if}
            </div>

          <!-- Timestamp e ações -->
          <div
            class={`flex items-center gap-2 mt-1 px-3 ${isMinha ? "justify-end" : "justify-start"}`}
          >
            <p class="text-xs text-base-content/50">
              {formatarDataMensagem(mensagem.enviadaEm)}
            </p>
            {#if isMinha && !mensagem.deletada && !mensagem.agendadaPara}
              <div class="flex gap-1">
                <button
                  class="text-xs text-base-content/50 hover:text-primary transition-colors"
                  onclick={() => editarMensagem(mensagem)}
                  title="Editar mensagem"
                >
                  ✏️
                </button>
                <button
                  class="text-xs text-base-content/50 hover:text-error transition-colors"
                  onclick={() => deletarMensagem(mensagem._id)}
                  title="Deletar mensagem"
                >
                  🗑️
                </button>
              </div>
            {/if}
          </div>
          </div>
        </div>
      {/each}
    {/each}

    <!-- Indicador de digitação -->
    {#if digitando?.data && digitando.data.length > 0}
      <div class="flex items-center gap-2 mb-4">
        <div class="flex items-center gap-1">
          <div class="w-2 h-2 rounded-full bg-base-content/50 animate-bounce"></div>
          <div
            class="w-2 h-2 rounded-full bg-base-content/50 animate-bounce"
            style="animation-delay: 0.1s;"
          ></div>
          <div
            class="w-2 h-2 rounded-full bg-base-content/50 animate-bounce"
            style="animation-delay: 0.2s;"
          ></div>
        </div>
        <p class="text-xs text-base-content/60">
          {digitando.data.map((u: { nome: string }) => u.nome).join(", ")} {digitando.data.length === 1
            ? "está digitando"
            : "estão digitando"}...
        </p>
      </div>
    {/if}
  {:else if !mensagens?.data}
    <!-- Loading -->
    <div class="flex items-center justify-center h-full">
      <span class="loading loading-spinner loading-lg"></span>
    </div>
  {:else}
    <!-- Vazio -->
    <div class="flex flex-col items-center justify-center h-full text-center">
      <svg
        xmlns="http://www.w3.org/2000/svg"
        fill="none"
        viewBox="0 0 24 24"
        stroke-width="1.5"
        stroke="currentColor"
        class="w-16 h-16 text-base-content/30 mb-4"
      >
        <path
          stroke-linecap="round"
          stroke-linejoin="round"
          d="M7.5 8.25h9m-9 3H12m-9.75 1.51c0 1.6 1.123 2.994 2.707 3.227 1.129.166 2.27.293 3.423.379.35.026.67.21.865.501L12 21l2.755-4.133a1.14 1.14 0 0 1 .865-.501 48.172 48.172 0 0 0 3.423-.379c1.584-.233 2.707-1.626 2.707-3.228V6.741c0-1.602-1.123-2.995-2.707-3.228A48.394 48.394 0 0 0 12 3c-2.392 0-4.744.175-7.043.513C3.373 3.746 2.25 5.14 2.25 6.741v6.018Z"
        />
      </svg>
      <p class="text-base-content/70">Nenhuma mensagem ainda</p>
      <p class="text-sm text-base-content/50 mt-1">Envie a primeira mensagem!</p>
    </div>
  {/if}
</div>

