// Acompanhamento em Tempo Real de UMA acao — orcamento 310, item 4.
//
// Ja existia o PainelPromotores (Freelancers > Acompanhamento), mas ele e
// global: mostra as ultimas 100 escalas de todos os eventos. No dia da campanha
// a producao nao quer isso — quer UMA acao na tela, sabendo quem chegou, quem
// nao chegou e o que ja foi registrado. E esta a promessa do orcamento 310.
//
// Atualiza sozinho por realtime (mesmo canal da migration 028): quando a
// promotora da check-in no celular, a linha muda aqui sem ninguem apertar F5.

const ACOMP_STATUS_CORES = {
  'Convidado':  { bg: '#F1F5F9', fg: '#475569', rotulo: 'Aguardando' },
  'Confirmado': { bg: '#EFF6FF', fg: '#1D4ED8', rotulo: 'Confirmado' },
  'Recusado':   { bg: '#FEF2F2', fg: '#B91C1C', rotulo: 'Recusou' },
  'Check-in':   { bg: '#F0FDF4', fg: '#15803D', rotulo: 'Presente' },
  'Concluído':  { bg: '#F0FDF4', fg: '#166534', rotulo: 'Concluiu' },
  'Falta':      { bg: '#FEF2F2', fg: '#B91C1C', rotulo: 'Falta' },
};

const fmtAcompHora = iso => iso
  ? new Date(iso).toLocaleTimeString('pt-BR', { hour: '2-digit', minute: '2-digit' })
  : null;

function TileAcomp({ rotulo, valor, cor, destaque }) {
  return (
    <div style={{ background: destaque || '#F8FAFC', borderRadius: DS.radius.sm, padding: '10px 12px', minWidth: 0 }}>
      <div style={{ fontSize: 20, fontWeight: 800, color: cor || DS.colors.text, lineHeight: 1.1 }}>{valor}</div>
      <div style={{ fontSize: 10, fontWeight: 700, color: DS.colors.textMuted, textTransform: 'uppercase', letterSpacing: '0.05em', marginTop: 3 }}>
        {rotulo}
      </div>
    </div>
  );
}

function AcompanhamentoEvento({ event }) {
  const [escalas, setEscalas] = React.useState([]);
  const [fotos, setFotos] = React.useState([]);
  const [historico, setHistorico] = React.useState({});
  const [loading, setLoading] = React.useState(true);
  const [ocorrencias, setOcorrencias] = React.useState([]);
  const [fotoAberta, setFotoAberta] = React.useState(null);
  const [respostas, setRespostas] = React.useState({});

  const carregar = React.useCallback(async () => {
    if (!event || !event.id) return;
    const [{ data: es, error: erEs }, { data: fo, error: erFo }, { data: oc }] = await Promise.all([
      sb.from('event_escalas')
        .select('*, freelancers(id, name, phone, photo_url)')
        .eq('event_id', event.id)
        .order('created_at'),
      sb.from('escala_fotos')
        .select('*, freelancers(name)')
        .eq('event_id', event.id)
        .order('enviada_em', { ascending: false }),
      sb.from('escala_ocorrencias')
        .select('*, freelancers(name)')
        .eq('event_id', event.id)
        .order('criada_em', { ascending: false }),
    ]);
    if (erEs) console.error('[AcompanhamentoEvento.escalas] Supabase error:', erEs);
    if (erFo) console.error('[AcompanhamentoEvento.fotos] Supabase error:', erFo);
    setEscalas(es || []);
    setFotos(fo || []);
    setOcorrencias(oc || []);
    setLoading(false);

    // Historico basico por profissional (item 4 do orcamento): quantas acoes ja
    // concluiu e quantas faltou. Uma consulta so para a equipe inteira.
    const ids = (es || []).map(e => e.freelancer_id);
    if (ids.length) {
      const { data: hist } = await sb.from('event_escalas')
        .select('freelancer_id, status')
        .in('freelancer_id', ids)
        .neq('event_id', event.id);
      const mapa = {};
      (hist || []).forEach(h => {
        if (!mapa[h.freelancer_id]) mapa[h.freelancer_id] = { concluidas: 0, faltas: 0 };
        if (h.status === 'Concluído') mapa[h.freelancer_id].concluidas++;
        if (h.status === 'Falta' || h.status === 'Recusado') mapa[h.freelancer_id].faltas++;
      });
      setHistorico(mapa);
    }
  }, [event && event.id]);

  React.useEffect(() => {
    carregar();
    if (!event || !event.id) return;
    const canal = sb.channel('acomp-evento-' + event.id)
      .on('postgres_changes', { event: '*', schema: 'public', table: 'event_escalas', filter: 'event_id=eq.' + event.id }, carregar)
      .on('postgres_changes', { event: '*', schema: 'public', table: 'escala_fotos', filter: 'event_id=eq.' + event.id }, carregar)
      .on('postgres_changes', { event: '*', schema: 'public', table: 'escala_ocorrencias', filter: 'event_id=eq.' + event.id }, carregar)
      .subscribe();
    return () => { sb.removeChannel(canal); };
  }, [carregar, event && event.id]);

  const resumo = React.useMemo(() => {
    const r = { total: escalas.length, presentes: 0, semCheckin: 0, recusas: 0, concluidos: 0 };
    escalas.forEach(e => {
      if (e.status === 'Recusado') r.recusas++;
      else if (e.check_in_em) { r.presentes++; if (e.check_out_em) r.concluidos++; }
      else r.semCheckin++;
    });
    return r;
  }, [escalas]);

  // Consolida os indicadores da acao somando o que cada profissional registrou.
  const campos = (event && event.resultado_campos) || [];
  const totaisResultados = React.useMemo(() => {
    const t = {};
    campos.forEach(c => { t[c.chave] = 0; });
    escalas.forEach(e => {
      const r = e.resultados || {};
      campos.forEach(c => {
        const v = parseFloat(r[c.chave]);
        if (Number.isFinite(v)) t[c.chave] += v;
      });
    });
    return t;
  }, [escalas, campos]);

  const ocorrenciasAbertas = ocorrencias.filter(o => !o.resolvida_em);

  // Responder e fechar em um passo so: a producao esta no meio da operacao,
  // nao vai abrir uma tela separada para cada problema.
  const resolver = async (oc) => {
    const texto = (respostas[oc.id] || '').trim();
    const { error } = await sb.from('escala_ocorrencias').update({
      resolvida_em: new Date().toISOString(),
      resposta: texto || null,
    }).eq('id', oc.id);
    if (error) { console.error('[AcompanhamentoEvento.resolver] Supabase error:', error); return; }
    carregar();
  };

  if (loading) return <Spinner />;

  if (!escalas.length) {
    return <EmptyState icon="users" title="Ninguém escalado ainda"
      desc="Escale a equipe na aba Escala para acompanhar a ação aqui." />;
  }

  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
      {/* Resumo ao vivo */}
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(112px, 1fr))', gap: 8 }}>
        <TileAcomp rotulo="Escalados" valor={resumo.total} />
        <TileAcomp rotulo="Presentes" valor={resumo.presentes} cor="#15803D" destaque="#F0FDF4" />
        <TileAcomp rotulo="Sem check-in" valor={resumo.semCheckin}
          cor={resumo.semCheckin ? '#B91C1C' : undefined} destaque={resumo.semCheckin ? '#FEF2F2' : undefined} />
        <TileAcomp rotulo="Recusas" valor={resumo.recusas}
          cor={resumo.recusas ? '#B91C1C' : undefined} destaque={resumo.recusas ? '#FEF2F2' : undefined} />
        <TileAcomp rotulo="Fotos" valor={fotos.length} />
        <TileAcomp rotulo="Ocorrências" valor={ocorrenciasAbertas.length}
          cor={ocorrenciasAbertas.length ? '#B91C1C' : undefined} destaque={ocorrenciasAbertas.length ? '#FEF2F2' : undefined} />
        <TileAcomp rotulo="Encerraram" valor={resumo.concluidos} />
      </div>

      {/* Indicadores da acao */}
      {campos.length > 0 && (
        <div>
          <div style={{ fontSize: 11, fontWeight: 700, color: DS.colors.textMuted, textTransform: 'uppercase', letterSpacing: '0.06em', marginBottom: 8 }}>
            Resultados registrados
          </div>
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(120px, 1fr))', gap: 8 }}>
            {campos.map(c => {
              const feito = totaisResultados[c.chave] || 0;
              const meta = parseFloat(c.meta);
              const temMeta = Number.isFinite(meta) && meta > 0;
              const pct = temMeta ? Math.round((feito / meta) * 100) : null;
              return (
                <div key={c.chave} style={{ background: '#F8FAFC', borderRadius: DS.radius.sm, padding: '10px 12px' }}>
                  <div style={{ fontSize: 18, fontWeight: 800, color: DS.colors.text }}>
                    {feito.toLocaleString('pt-BR')}
                    {temMeta && (
                      <span style={{ fontSize: 12, fontWeight: 700, color: DS.colors.textMuted }}> / {meta.toLocaleString('pt-BR')}</span>
                    )}
                  </div>
                  <div style={{ fontSize: 10, fontWeight: 700, color: DS.colors.textMuted, textTransform: 'uppercase', letterSpacing: '0.05em', marginTop: 3 }}>
                    {c.label}
                  </div>
                  {pct !== null && (
                    <div style={{ fontSize: 11, fontWeight: 700, marginTop: 4, color: pct >= 100 ? DS.colors.success : DS.colors.textSec }}>
                      {pct}% da meta
                    </div>
                  )}
                </div>
              );
            })}
          </div>
        </div>
      )}

      {/* Equipe */}
      <div>
        <div style={{ fontSize: 11, fontWeight: 700, color: DS.colors.textMuted, textTransform: 'uppercase', letterSpacing: '0.06em', marginBottom: 8 }}>
          Equipe da ação
        </div>
        <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
          {escalas.map(e => {
            const f = e.freelancers || {};
            const cor = ACOMP_STATUS_CORES[e.status] || ACOMP_STATUS_CORES.Convidado;
            const h = historico[e.freelancer_id];
            const dist = e.check_in_distancia_m != null ? fmtDistancia(Number(e.check_in_distancia_m)) : null;
            const linhaStatus = e.check_in_em
              ? 'Chegou ' + fmtAcompHora(e.check_in_em) + (dist ? ' · a ' + dist + ' do local' : '')
              : (e.status === 'Recusado' ? 'Recusou a escala' : 'Ainda não fez check-in');
            return (
              <div key={e.id} style={{ display: 'flex', alignItems: 'center', gap: 10, border: '1px solid ' + DS.colors.border, borderRadius: DS.radius.sm, padding: 10 }}>
                {e.check_in_foto_url ? (
                  <img src={e.check_in_foto_url} alt="" onClick={() => setFotoAberta(e.check_in_foto_url)}
                    style={{ width: 42, height: 42, borderRadius: 10, objectFit: 'cover', cursor: 'pointer', flexShrink: 0 }} />
                ) : (
                  <Avatar name={f.name || 'x'} size={42} src={f.photo_url} />
                )}

                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{ fontSize: 13, fontWeight: 700, color: DS.colors.text, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
                    {f.name || 'Sem nome'}
                    <span style={{ fontWeight: 600, color: DS.colors.textMuted }}> · {e.funcao}</span>
                  </div>
                  <div style={{ fontSize: 11, color: DS.colors.textSec, marginTop: 2 }}>
                    {linhaStatus}
                    {e.check_out_em ? ' · saiu ' + fmtAcompHora(e.check_out_em) : ''}
                  </div>
                  {h && (h.concluidas || h.faltas) ? (
                    <div style={{ fontSize: 10, color: DS.colors.textMuted, marginTop: 2 }}>
                      Histórico: {h.concluidas} concluídas · {h.faltas} faltas/recusas
                    </div>
                  ) : null}
                </div>

                <div style={{ fontSize: 11, fontWeight: 800, padding: '4px 10px', borderRadius: 999, background: cor.bg, color: cor.fg, flexShrink: 0 }}>
                  {cor.rotulo}
                </div>
              </div>
            );
          })}
        </div>
      </div>

      {/* Ocorrencias — o que a producao precisa ver primeiro */}
      {ocorrencias.length > 0 && (
        <div>
          <div style={{ fontSize: 11, fontWeight: 700, color: DS.colors.textMuted, textTransform: 'uppercase', letterSpacing: '0.06em', marginBottom: 8 }}>
            Ocorrências ({ocorrenciasAbertas.length} em aberto)
          </div>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
            {ocorrencias.map(o => (
              <div key={o.id} style={{
                border: '1px solid ' + DS.colors.border, borderRadius: DS.radius.sm, padding: 10,
                borderLeft: '3px solid ' + (o.resolvida_em ? DS.colors.success : DS.colors.danger),
                background: o.resolvida_em ? '#fff' : '#FEF2F2',
              }}>
                <div style={{ display: 'flex', gap: 10, alignItems: 'flex-start' }}>
                  {o.foto_url && (
                    <img src={o.foto_url} alt="" onClick={() => setFotoAberta(o.foto_url)}
                      style={{ width: 48, height: 48, borderRadius: 8, objectFit: 'cover', cursor: 'pointer', flexShrink: 0 }} />
                  )}
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={{ fontSize: 13, fontWeight: 800, color: DS.colors.text }}>{o.categoria}</div>
                    <div style={{ fontSize: 12, color: DS.colors.textSec, marginTop: 2, whiteSpace: 'pre-wrap' }}>{o.descricao}</div>
                    <div style={{ fontSize: 10, color: DS.colors.textMuted, marginTop: 3 }}>
                      {(o.freelancers && o.freelancers.name) || '—'} · {fmtAcompHora(o.criada_em)}
                      {o.endereco ? ' · ' + o.endereco : ''}
                    </div>
                    {o.resposta && (
                      <div style={{ fontSize: 12, marginTop: 6, background: '#F0FDF4', borderRadius: 6, padding: '6px 8px' }}>
                        <b>Resposta:</b> {o.resposta}
                      </div>
                    )}
                  </div>
                </div>

                {!o.resolvida_em && (
                  <div style={{ display: 'grid', gridTemplateColumns: '1fr auto', gap: 8, marginTop: 8 }}>
                    <Input value={respostas[o.id] || ''}
                      onChange={v => setRespostas(r => ({ ...r, [o.id]: v }))}
                      placeholder="Resposta para o profissional (opcional)" />
                    <Btn size="sm" variant="success" icon="check" onClick={() => resolver(o)}>Resolver</Btn>
                  </div>
                )}
              </div>
            ))}
          </div>
        </div>
      )}

      {/* Fotos recebidas */}
      {fotos.length > 0 && (
        <div>
          <div style={{ fontSize: 11, fontWeight: 700, color: DS.colors.textMuted, textTransform: 'uppercase', letterSpacing: '0.06em', marginBottom: 8 }}>
            Fotos recebidas ({fotos.length})
          </div>
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(104px, 1fr))', gap: 8 }}>
            {fotos.map(ft => (
              <div key={ft.id} style={{ minWidth: 0 }}>
                <img src={ft.url} alt="" onClick={() => setFotoAberta(ft.url)}
                  style={{ width: '100%', aspectRatio: '1', objectFit: 'cover', borderRadius: 8, cursor: 'pointer', display: 'block' }} />
                <div style={{ fontSize: 10, fontWeight: 700, color: DS.colors.text, marginTop: 4 }}>{ft.categoria || 'Outros'}</div>
                <div style={{ fontSize: 10, color: DS.colors.textMuted, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
                  {(ft.freelancers && ft.freelancers.name) || ''} · {fmtAcompHora(ft.enviada_em)}
                </div>
                {ft.legenda && (
                  <div style={{ fontSize: 10, color: DS.colors.textSec, marginTop: 2 }}>{ft.legenda}</div>
                )}
              </div>
            ))}
          </div>
        </div>
      )}

      {/* Lightbox — a producao amplia a foto de chegada quando o cliente cobra */}
      {fotoAberta && (
        <div onClick={() => setFotoAberta(null)}
          style={{ position: 'fixed', inset: 0, background: 'rgba(15,23,42,0.85)', zIndex: 1200, display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 24, cursor: 'zoom-out' }}>
          <img src={fotoAberta} alt="" style={{ maxWidth: '100%', maxHeight: '100%', borderRadius: 10 }} />
        </div>
      )}
    </div>
  );
}

Object.assign(window, { AcompanhamentoEvento });
