/* ============================================================
   KeS Metas — App raiz: estado, navegação, papéis
   O estado vive em memória (useReducer) e é PERSISTIDO no Firebase
   quando configurado (ver firebase.js + PASSO-A-PASSO-FIREBASE.md).
   ============================================================ */
const { useReducer, useEffect, useRef } = React;

// Fatias do estado que são salvas no banco de dados (Firebase).
// As SENHAS nunca vão para o banco — ficam no cofre do Firebase Authentication.
function semSenha(u) { const c = { ...u }; delete c.senha; return c; }
function dbSlice(s) {
  return { users: s.users.map(semSenha), metas: s.metas, activities: s.activities, meetings: s.meetings, stages: s.stages, leads: s.leads };
}

const NEW_COLORS = ["#E03C31", "#3E8EDE", "#2BB673", "#F2A93B", "#9B6BD6", "#E0689A", "#48B3C7"];

function initState() {
  const s = window.KES.seed;
  return {
    users: s.users.map((u) => ({ ...u })),
    metas: JSON.parse(JSON.stringify(s.metas)),
    activities: s.activities.map((a) => ({ ...a })),
    meetings: s.meetings.map((m) => ({ ...m })),
    stages: s.stages.map((st) => ({ ...st })),
    leads: s.leads.map((l) => ({ ...l, tags: [...(l.tags || [])] })),
    google: { connected: true, account: window.KES.GoogleCalendarService.account },
    agendaPrefill: null,
    session: null,
    authEmail: null,       // e-mail logado no Firebase (login seguro)
    view: "dashboard",
    scope: "all",          // contexto do admin: 'all' (equipe) ou userId
    period: window.buildPreset("mes"),
    toast: null,
  };
}

function reducer(state, action) {
  switch (action.type) {
    case "LOGIN":
      return { ...state, session: action.user.id, view: "dashboard", scope: "all", period: window.buildPreset("mes") };
    case "SET_AUTH_EMAIL": {
      // Login seguro do Firebase resolveu: casa o e-mail com o usuário do sistema.
      if (!action.email) return { ...state, authEmail: null, session: null };
      const u = state.users.find((x) => x.email.toLowerCase() === action.email.toLowerCase());
      return { ...state, authEmail: action.email, session: u ? u.id : null, view: "dashboard", scope: "all", period: window.buildPreset("mes") };
    }
    case "LOGOUT":
      return { ...state, session: null, authEmail: null };
    case "SET_VIEW":
      return { ...state, view: action.view };
    case "SET_PERIOD":
      return { ...state, period: action.period };
    case "SET_SCOPE":
      return { ...state, scope: action.scope };
    case "OPEN_USER":
      return { ...state, scope: action.userId, view: "dashboard" };
    case "TOAST":
      return { ...state, toast: { msg: action.msg, id: Date.now() } };
    case "CLEAR_TOAST":
      return { ...state, toast: null };

    case "UPSERT_ACTIVITY": {
      const idx = state.activities.findIndex((a) => a.userId === action.userId && a.date === action.date);
      const activities = state.activities.slice();
      if (idx >= 0) activities[idx] = { ...activities[idx], ...action.patch };
      else activities.push({ id: "a" + Date.now(), userId: action.userId, date: action.date, ligacoes: 0, conexoes: 0, reunioesRealizadas: 0, reunioesQualificadas: 0, vendas: 0, valorVendas: 0, ...action.patch });
      return { ...state, activities };
    }
    case "ADD_MEETING": {
      // // AQUI: integrar com backend/banco de dados (persistir agendamento)
      let leads = state.leads;
      if (action.meeting.leadId) {
        const reuniao = state.stages.find((s) => /reuni/i.test(s.nome) && s.tipo === "open");
        if (reuniao) leads = state.leads.map((l) => l.id === action.meeting.leadId ? { ...l, stageId: reuniao.id } : l);
      }
      return { ...state, meetings: [...state.meetings, action.meeting], leads };
    }
    case "DELETE_MEETING":
      return { ...state, meetings: state.meetings.filter((m) => m.id !== action.id) };

    /* ---------- CRM ---------- */
    case "ADD_LEAD": {
      const lead = { id: "l" + Date.now(), createdAt: window.KES.iso(window.KES.SIM_TODAY), tags: [], ...action.lead };
      return { ...state, leads: [lead, ...state.leads] };
    }
    case "UPDATE_LEAD":
      return { ...state, leads: state.leads.map((l) => l.id === action.id ? { ...l, ...action.patch } : l) };
    case "DELETE_LEAD":
      return { ...state, leads: state.leads.filter((l) => l.id !== action.id) };
    case "MOVE_LEAD":
      return { ...state, leads: state.leads.map((l) => l.id === action.id ? { ...l, stageId: action.stageId } : l) };
    case "IMPORT_LEADS":
      // // AQUI: integrar com backend/banco de dados (gravar leads importados)
      return { ...state, leads: [...action.leads, ...state.leads] };
    case "SET_STAGES": {
      const validIds = new Set(action.stages.map((s) => s.id));
      const fallback = action.stages[0].id;
      const leads = state.leads.map((l) => validIds.has(l.stageId) ? l : { ...l, stageId: fallback });
      return { ...state, stages: action.stages, leads };
    }
    case "AGENDAR_LEAD":
      return { ...state, agendaPrefill: action.lead, view: "agenda" };
    case "CLEAR_PREFILL":
      return { ...state, agendaPrefill: null };

    case "ADD_USER": {
      const id = action.user.id || ("u" + Date.now());
      const cor = NEW_COLORS[state.users.length % NEW_COLORS.length];
      // Sem senha: a credencial fica no Firebase Authentication.
      const u = { id, nome: action.user.nome.trim(), email: action.user.email.trim(), papel: action.user.papel, googleConnected: false, cor, fator: 1 };
      return { ...state, users: [...state.users, u] };
    }
    case "UPDATE_USER": {
      const users = state.users.map((u) => {
        if (u.id !== action.id) return u;
        const patch = { ...action.patch };
        if (!patch.senha) delete patch.senha; // mantém senha se vazio
        return { ...u, ...patch };
      });
      return { ...state, users };
    }
    case "DELETE_USER":
      return {
        ...state,
        users: state.users.filter((u) => u.id !== action.id),
        activities: state.activities.filter((a) => a.userId !== action.id),
        meetings: state.meetings.filter((m) => m.userId !== action.id),
        leads: state.leads.filter((l) => l.responsavelId !== action.id),
        scope: state.scope === action.id ? "all" : state.scope,
      };
    case "SET_GOOGLE":
      return { ...state, google: { ...state.google, connected: action.connected } };
    case "SET_METAS":
      return { ...state, metas: action.metas };
    case "HYDRATE": {
      // Substitui os dados pelos vindos do banco (Firebase), preservando a sessão/UI.
      const next = { ...state, ...action.data };
      // Se já há um e-mail logado, recalcula a sessão pelos usuários recém-carregados.
      if (state.authEmail) {
        const u = next.users.find((x) => x.email.toLowerCase() === state.authEmail.toLowerCase());
        next.session = u ? u.id : null;
      }
      return next;
    }
    default:
      return state;
  }
}

const NAV = [
  { id: "dashboard", label: "Painel", icon: "dashboard" },
  { id: "crm", label: "CRM", icon: "funnel" },
  { id: "agenda", label: "Agenda", icon: "calendar" },
  { id: "consolidado", label: "Equipe", icon: "users", adminOnly: true },
  { id: "usuarios", label: "Usuários", icon: "user", adminOnly: true },
  { id: "metas", label: "Metas", icon: "sliders", adminOnly: true },
];

function getSubject(state, viewer) {
  if (viewer.papel === "comum") return { isTeam: false, user: viewer, userIds: [viewer.id] };
  if (state.scope === "all") return { isTeam: true, userIds: state.users.map((u) => u.id), label: "Equipe" };
  const u = state.users.find((x) => x.id === state.scope) || viewer;
  return { isTeam: false, user: u, userIds: [u.id] };
}

function App() {
  const [state, dispatch] = useReducer(reducer, undefined, initState);

  // ---- Persistência no Firebase (quando configurado) ----
  const dbReady = useRef(false);     // já recebeu os dados do banco?
  const lastSync = useRef("");       // último JSON salvo/recebido (evita laço)

  useEffect(() => {
    const DB = window.KESDB;
    if (!DB || !DB.configured() || !DB.init()) return; // sem Firebase → modo memória
    const unsub = DB.subscribe((data, pending) => {
      if (pending) return; // ignora o "eco" da nossa própria gravação
      if (!data) {
        // Primeiro uso: banco vazio → grava o estado inicial (admin + etapas).
        // Sem senha: a credencial do admin fica no Firebase Authentication.
        const seed = { users: window.KES.seed.users.map(semSenha), metas: window.KES.seed.metas, activities: [], meetings: [], stages: window.KES.seed.stages, leads: [] };
        lastSync.current = JSON.stringify(seed);
        DB.save(seed);
        dbReady.current = true;
        dispatch({ type: "HYDRATE", data: seed });
        return;
      }
      lastSync.current = JSON.stringify(dbSlice(data));
      dbReady.current = true;
      dispatch({ type: "HYDRATE", data: {
        users: data.users || [], metas: data.metas || window.KES.seed.metas,
        activities: data.activities || [], meetings: data.meetings || [],
        stages: data.stages || window.KES.seed.stages, leads: data.leads || [],
      } });
    });
    return unsub;
  }, []);

  // Salva no banco sempre que os dados mudarem (após a 1ª carga).
  useEffect(() => {
    const DB = window.KESDB;
    if (!DB || !DB.configured() || !dbReady.current) return;
    const json = JSON.stringify(dbSlice(state));
    if (json === lastSync.current) return; // nada mudou de fato
    lastSync.current = json;
    DB.save(dbSlice(state));
  }, [state.users, state.metas, state.activities, state.meetings, state.stages, state.leads]);

  // ---- Login seguro do Firebase (Authentication) ----
  // Escuta quem está logado e casa o e-mail com o usuário do sistema.
  useEffect(() => {
    const A = window.KESAUTH;
    if (!A || !A.configured() || !A.init()) return; // sem Firebase → login local (fallback)
    const unsub = A.onAuth((user) => {
      dispatch({ type: "SET_AUTH_EMAIL", email: user ? user.email : null });
    });
    return unsub;
  }, []);

  function logout() {
    if (window.KESAUTH && window.KESAUTH.configured()) window.KESAUTH.signOut();
    dispatch({ type: "LOGOUT" });
  }

  useEffect(() => {
    if (!state.toast) return;
    const t = setTimeout(() => dispatch({ type: "CLEAR_TOAST" }), 3200);
    return () => clearTimeout(t);
  }, [state.toast && state.toast.id]);

  if (!state.session) {
    return (<><LoginScreen state={state} dispatch={dispatch} onLogin={(u) => dispatch({ type: "LOGIN", user: u })} /><Toast toast={state.toast && state.toast.msg} /></>);
  }

  const viewer = state.users.find((u) => u.id === state.session);
  if (!viewer) { dispatch({ type: "LOGOUT" }); return null; }
  const isAdmin = viewer.papel === "admin";
  const nav = NAV.filter((n) => !n.adminOnly || isAdmin);
  // garante que comum nunca fique numa view de admin
  const view = (!isAdmin && ["consolidado", "usuarios", "metas"].includes(state.view)) ? "dashboard" : state.view;

  const subject = getSubject(state, viewer);
  const scopeSelect = isAdmin ? (
    <Field label={null}>
      <select className="field" value={state.scope} onChange={(e) => dispatch({ type: "SET_SCOPE", scope: e.target.value })} style={{ minWidth: 170, paddingTop: 10, paddingBottom: 10 }}>
        <option value="all">Equipe inteira</option>
        {state.users.map((u) => <option key={u.id} value={u.id}>{u.nome}{u.id === viewer.id ? " (você)" : ""}</option>)}
      </select>
    </Field>
  ) : null;

  let screen = null;
  if (view === "dashboard") screen = <DashboardScreen state={state} dispatch={dispatch} viewer={viewer} subject={subject} extraActions={scopeSelect} />;
  else if (view === "crm") screen = <CRMScreen state={state} dispatch={dispatch} viewer={viewer} />;
  else if (view === "agenda") screen = <AgendaScreen state={state} dispatch={dispatch} viewer={viewer} />;
  else if (view === "consolidado") screen = <ConsolidadoScreen state={state} dispatch={dispatch} viewer={viewer} />;
  else if (view === "usuarios") screen = <UsuariosScreen state={state} dispatch={dispatch} viewer={viewer} />;
  else if (view === "metas") screen = <ConfigurarMetasScreen state={state} dispatch={dispatch} />;

  return (
    <div className="app-shell">
      {/* Sidebar (desktop) */}
      <aside className="sidebar">
        <div className="sidebar-brand">
          <Logo size={38} />
          <div><div className="bn">KeS Metas</div><div className="bs">Comercial</div></div>
        </div>
        <nav className="nav">
          <div className="nav-section">Menu</div>
          {nav.map((n) => (
            <button key={n.id} className={"nav-item" + (view === n.id ? " active" : "")} onClick={() => dispatch({ type: "SET_VIEW", view: n.id })}>
              <Icon name={n.icon} size={19} />{n.label === "Painel" ? "Painel de Metas" : n.label === "Agenda" ? "Agendamentos" : n.label === "Equipe" ? "Visão da Equipe" : n.label === "Metas" ? "Configurar Metas" : n.label}
            </button>
          ))}
        </nav>
        <div className="sidebar-foot">
          <div className="userchip">
            <Avatar user={viewer} size={40} />
            <div className="meta"><div className="nm">{viewer.nome}</div><div className="rl">{isAdmin ? "Administrador" : "Usuário comum"}</div></div>
            <button className="iconbtn" title="Sair" onClick={logout}><Icon name="logout" size={19} /></button>
          </div>
        </div>
      </aside>

      {/* Conteúdo */}
      <div className="main">
        {/* App bar mobile */}
        <div className="mobile-appbar">
          <div className="mb-brand"><Logo size={30} /><div className="bn">KeS Metas</div></div>
          <button className="iconbtn" title="Sair" onClick={logout}><Icon name="logout" size={20} /></button>
        </div>
        {screen}
      </div>

      {/* Bottom nav mobile */}
      <nav className="bottomnav">
        {nav.map((n) => (
          <button key={n.id} className={"bn-item" + (view === n.id ? " active" : "")} onClick={() => dispatch({ type: "SET_VIEW", view: n.id })}>
            <Icon name={n.icon} size={21} /><span>{n.label}</span>
          </button>
        ))}
      </nav>

      <Toast toast={state.toast && state.toast.msg} />
    </div>
  );
}

ReactDOM.createRoot(document.getElementById("root")).render(<App />);
