// Main app — routing + state + iPhone shell

const { useState, useEffect, useRef, useCallback } = React;

// ─── Persistência local (localStorage) ────────────────────────────
const STORAGE_KEY = 'cdv:state:v1';
const BOOTSTRAP_KEY = 'cdv:bootstrapped:v1';

function loadState() {
  try {
    const raw = localStorage.getItem(STORAGE_KEY);
    if (!raw) return null;
    const parsed = JSON.parse(raw);
    return parsed && typeof parsed === 'object' ? parsed : null;
  } catch (e) {
    return null;
  }
}

function loadBootstrap() {
  try {
    return localStorage.getItem(BOOTSTRAP_KEY) === '1';
  } catch (e) {
    return false;
  }
}

const USER_KEY = 'cdv:user:v1';
function loadUser() {
  try {
    const raw = localStorage.getItem(USER_KEY);
    return raw ? JSON.parse(raw) : null;
  } catch (e) {
    return null;
  }
}
function persistUser(user) {
  try {
    if (user) localStorage.setItem(USER_KEY, JSON.stringify(user));
    else localStorage.removeItem(USER_KEY);
  } catch (e) {}
}

function persistState(state) {
  try {
    localStorage.setItem(STORAGE_KEY, JSON.stringify(state));
  } catch (e) {
    // storage cheio ou bloqueado — ignora silenciosamente
  }
}

function resetAllData() {
  try {
    localStorage.removeItem(STORAGE_KEY);
    localStorage.removeItem(BOOTSTRAP_KEY);
    localStorage.removeItem(USER_KEY);
  } catch (e) {}
}

// ─── Preferência de tema ──────────────────────────────────────────
const THEME_PREF_KEY = 'cdv:themePref:v1';
function loadThemePref() {
  try {
    const v = localStorage.getItem(THEME_PREF_KEY);
    return v === 'light' || v === 'dark' || v === 'auto' ? v : 'auto';
  } catch (e) { return 'auto'; }
}
function saveThemePref(pref) {
  try { localStorage.setItem(THEME_PREF_KEY, pref); } catch (e) {}
}
// Aplica tema sincronamente antes da hidratação do React para evitar flash
(function applyInitialTheme() {
  try {
    const pref = loadThemePref();
    const mode = window.resolveTheme ? window.resolveTheme(pref) : 'dark';
    if (window.applyTheme) window.applyTheme(mode);
  } catch (e) {}
})();

// Expor reset global para o cliente poder limpar dados via console se precisar
window.CDV_RESET = resetAllData;

const PhoneShell = ({ children, dark = true }) => (
  <div style={{
    width: 402, height: 870, borderRadius: 56,
    background: '#000', position: 'relative', overflow: 'hidden',
    boxShadow: `
      0 50px 100px -20px rgba(0,0,0,0.55),
      0 30px 60px -30px rgba(124,92,255,0.20),
      0 0 0 9px #16151B,
      0 0 0 10px rgba(255,255,255,0.04)
    `,
  }}>
    <div style={{
      width: '100%', height: '100%', background: CDV.bg,
      borderRadius: 48, overflow: 'hidden', position: 'relative',
    }}>
      {children}
    </div>
  </div>
);

const App = () => {
  const [bootstrapped, setBootstrapped] = useState(loadBootstrap);
  const [user, setUser] = useState(loadUser);
  const [profile, setProfile] = useState(null);
  const [route, setRoute] = useState(() => {
    try {
      const r = new URLSearchParams(location.search).get('route');
      const valid = ['dashboard','tasks','finance','habits','goals','calendar','ai','more','profile','achievements','plans','notifications','admin','vault'];
      return r && valid.includes(r) ? r : 'dashboard';
    } catch (e) { return 'dashboard'; }
  });
  const [toast, setToast] = useState({ text: '', visible: false, icon: 'check' });
  const toastTimer = useRef(null);
  const [syncStatus, setSyncStatus] = useState({ status: 'idle', lastSyncedAt: null });
  // Quando aplicamos um update vindo do cloud, evitamos disparar save em loop
  const skipNextCloudSaveRef = useRef(false);
  const debouncedSaveRef = useRef(null);

  // Tema
  const [themePref, setThemePref] = useState(loadThemePref);
  const [themeTick, setThemeTick] = useState(0); // força re-render quando tema muda

  // Push notifications: registra SW + re-agenda timers conforme tarefas mudam
  useEffect(() => {
    if (window.Push && window.Push.registerServiceWorker) {
      window.Push.registerServiceWorker();
    }
    // Listener pra mensagens vindas do SW (clique em notificação)
    if (navigator && navigator.serviceWorker) {
      const onMsg = (event) => {
        const data = event.data || {};
        if (data.type === 'NAVIGATE' && data.route) {
          setRoute(data.route);
        }
      };
      navigator.serviceWorker.addEventListener('message', onMsg);
      return () => navigator.serviceWorker.removeEventListener('message', onMsg);
    }
  }, []);

  const applyAndPersistTheme = useCallback((pref) => {
    setThemePref(pref);
    saveThemePref(pref);
    const mode = window.resolveTheme ? window.resolveTheme(pref) : 'dark';
    window.applyTheme && window.applyTheme(mode);
    setThemeTick(t => t + 1);
  }, []);

  // Re-aplicar tema quando preferência muda e, em 'auto', reavaliar a cada 5 min
  useEffect(() => {
    const mode = window.resolveTheme ? window.resolveTheme(themePref) : 'dark';
    window.applyTheme && window.applyTheme(mode);
    setThemeTick(t => t + 1);
    if (themePref !== 'auto') return;
    const interval = setInterval(() => {
      const next = window.resolveTheme ? window.resolveTheme('auto') : 'dark';
      if (next !== (window.CDV && window.CDV._mode)) {
        window.applyTheme && window.applyTheme(next);
        setThemeTick(t => t + 1);
      }
    }, 5 * 60 * 1000);
    return () => clearInterval(interval);
  }, [themePref]);

  // Sincronizar sessão Supabase ao montar e quando muda em outra aba/redirect OAuth
  useEffect(() => {
    if (!window.Auth) return;
    let mounted = true;
    window.Auth.getSession().then((u) => {
      if (mounted && u) {
        setUser(u);
        persistUser(u);
        // Se já tinha bootstrap salvo, mantém — senão considera logado e já bootstrapped
        if (!loadBootstrap()) setBootstrapped(true);
      }
    });
    const sub = window.Auth.onAuthStateChange((u) => {
      setUser(u);
      persistUser(u);
      if (u && !loadBootstrap()) setBootstrapped(true);
    });
    return () => { mounted = false; sub && sub.unsubscribe && sub.unsubscribe(); };
  }, []);

  const handleLogout = useCallback(async () => {
    try { window.Auth && await window.Auth.signOut(); } catch (e) {}
    setUser(null);
    setProfile(null);
    persistUser(null);
    setBootstrapped(false);
    setRoute('dashboard');
  }, []);

  // Carregar profile do user logado (papel admin, plano, etc.)
  useEffect(() => {
    if (!user || !user.id || user.isMock) { setProfile(null); return; }
    if (!window.AdminAPI) return;
    let cancelled = false;
    (async () => {
      const p = await window.AdminAPI.ensureProfile(user);
      if (!cancelled) setProfile(p);
    })();
    return () => { cancelled = true; };
  }, [user && user.id]);

  const [state, setState] = useState(() => {
    const saved = loadState();
    if (saved) return saved;
    // Sem state salvo: se Supabase está configurado (usuário real), começa LIMPO.
    // Caso contrário (modo demo), carrega os dados de exemplo.
    // Atenção: o finance precisa ter a mesma estrutura do initialFinance
    // (saldo, categoriaGastos, cofrinhos etc) — várias telas leem direto.
    const cfg = window.Auth && window.Auth.isConfigured();
    if (cfg) {
      return {
        tasks: [], habits: [], goals: [],
        finance: {
          saldo: 0, entradas: 0, saidas: 0, budget: 0,
          cartao: 0, cartaoLimite: 0, vencimento: '',
          transactions: [], cofrinhos: [], categoriaGastos: [], cards: [],
        },
        events: [], vault: [], notifications: null,
        xp: 0, level: 1, streak: 0,
      };
    }
    return {
      tasks: initialTasks,
      habits: initialHabits,
      goals: initialGoals,
      finance: initialFinance,
      events: eventsToday,
      notifications: null,
      xp: 1830,
      level: 12,
      streak: 47,
    };
  });

  // Persistir state e flag de bootstrap a cada mudança
  useEffect(() => { persistState(state); }, [state]);

  // Re-agendar notificações sempre que tarefas mudarem
  useEffect(() => {
    if (window.Push && window.Push.rescheduleTasks) {
      window.Push.rescheduleTasks(state.tasks);
    }
  }, [state.tasks]);
  useEffect(() => {
    try { localStorage.setItem(BOOTSTRAP_KEY, bootstrapped ? '1' : '0'); } catch (e) {}
  }, [bootstrapped]);

  // ─── Cloud sync ─────────────────────────────────────────────
  // Quando o user fica disponível e o CloudSync está configurado:
  //  1. Inicializa debounced saver
  //  2. Carrega state da nuvem (resolve conflito com local via updated_at)
  //  3. Inscreve em UPDATEs realtime (outros dispositivos)
  useEffect(() => {
    if (!user || !user.id || user.isMock) return;
    if (!window.CloudSync || !window.CloudSync.isConfigured()) return;

    let cancelled = false;
    debouncedSaveRef.current = window.CloudSync.makeDebouncedSaver(1500);

    (async () => {
      setSyncStatus({ status: 'loading', lastSyncedAt: null });
      const cloud = await window.CloudSync.loadState(user.id);
      if (cancelled) return;

      if (cloud && cloud.data && Object.keys(cloud.data).length > 0) {
        // Tem dados na nuvem — aplica localmente sem disparar save de volta
        skipNextCloudSaveRef.current = true;
        setState(cloud.data);
        setSyncStatus({ status: 'saved', lastSyncedAt: cloud.updatedAt });
      } else {
        // Primeira sincronização: empurra o state atual pro cloud
        const res = await window.CloudSync.saveState(user.id, state);
        if (cancelled) return;
        setSyncStatus({ status: res.ok ? 'saved' : 'error', lastSyncedAt: new Date().toISOString() });
      }
    })();

    const unsubscribe = window.CloudSync.subscribe(user.id, (remoteData, updatedAt) => {
      // Atualiza local sem reenviar pro cloud
      skipNextCloudSaveRef.current = true;
      setState(remoteData);
      setSyncStatus({ status: 'saved', lastSyncedAt: updatedAt });
    });

    return () => {
      cancelled = true;
      unsubscribe && unsubscribe();
    };
  }, [user && user.id]);

  // Salva no cloud quando state muda (debounced)
  useEffect(() => {
    if (!user || !user.id || user.isMock) return;
    if (!window.CloudSync || !window.CloudSync.isConfigured()) return;
    if (!debouncedSaveRef.current) return;

    if (skipNextCloudSaveRef.current) {
      skipNextCloudSaveRef.current = false;
      return;
    }

    debouncedSaveRef.current(user.id, state, (info) => {
      if (info.status === 'pending') {
        setSyncStatus(s => ({ ...s, status: 'pending' }));
      } else if (info.status === 'saving') {
        setSyncStatus(s => ({ ...s, status: 'saving' }));
      } else if (info.status === 'saved') {
        setSyncStatus({ status: 'saved', lastSyncedAt: new Date().toISOString() });
      } else if (info.status === 'error') {
        setSyncStatus(s => ({ ...s, status: 'error' }));
      }
    });
  }, [state, user && user.id]);

  const showToast = useCallback((text, icon = 'check') => {
    clearTimeout(toastTimer.current);
    setToast({ text, icon, visible: true });
    toastTimer.current = setTimeout(() => setToast(t => ({ ...t, visible: false })), 1800);
  }, []);

  const navigate = (r) => setRoute(r);
  const openAI = () => setRoute('ai');

  // Map tab IDs to routes; 'more' covers a few inner pages
  const bottomTab = ['dashboard', 'tasks', 'ai', 'finance', 'more', 'profile', 'achievements', 'plans', 'notifications', 'goals', 'calendar', 'habits', 'admin', 'vault'].includes(route)
    ? (['profile', 'achievements', 'plans', 'notifications', 'goals', 'habits', 'calendar', 'admin', 'vault'].includes(route) ? 'more' : route)
    : 'dashboard';

  if (!bootstrapped) {
    return (
      <PhoneShell>
        <OnboardingFlow onComplete={(payload) => {
          if (payload && payload.user) { setUser(payload.user); persistUser(payload.user); }
          if (payload && payload.profile) {
            setState(s => ({ ...s, profile: payload.profile }));
          }
          if (payload && payload.paymentMethod && payload.user && payload.user.id && window.AdminAPI) {
            // Marca trial como ativo no Supabase
            const trialEnds = new Date();
            trialEnds.setDate(trialEnds.getDate() + 3);
            window.AdminAPI.updateMyProfile(payload.user.id, {
              plan: 'trial',
              trial_ends_at: trialEnds.toISOString(),
            }).catch(() => {});
            // Salva info do cartão localmente no state (último 4 + bandeira)
            setState(s => ({ ...s, paymentMethod: payload.paymentMethod }));
          }
          setBootstrapped(true);
        }} />
      </PhoneShell>
    );
  }

  // Guard: trial expirado → paywall obrigatório (admins passam direto)
  const trialStatus = window.Checkout && profile
    ? window.Checkout.checkTrialStatus(profile)
    : { expired: false, isPaying: false };
  const isAdminUser = profile && profile.role === 'admin';
  if (trialStatus.expired && !trialStatus.isPaying && !isAdminUser && window.MobilePaywall) {
    const refreshProfile = async () => {
      if (!window.AdminAPI || !user || !user.id) return;
      const p = await window.AdminAPI.ensureProfile(user);
      setProfile(p);
      showToast('Perfil atualizado');
    };
    return (
      <PhoneShell>
        <MobilePaywall user={user} onLogout={handleLogout} onRefresh={refreshProfile} showToast={showToast} />
      </PhoneShell>
    );
  }

  return (
    <PhoneShell>
      <StatusBar />
      <DynamicIsland>
        {route === 'ai' && (
          <>
            <div style={{
              width: 10, height: 10, borderRadius: 99, background: CDV.brand,
              animation: 'pulseGlow 1.5s ease-in-out infinite',
            }} />
            <span style={{ fontSize: 12, fontWeight: 500, color: CDV.text }}>Sofia ouvindo</span>
          </>
        )}
        {route === 'dashboard' && (
          <>
            <Icon name="flame" size={14} color={CDV.flame} />
            <span style={{ fontSize: 12, fontWeight: 600, color: CDV.text }}>47 dias</span>
            <span style={{ fontSize: 11, color: CDV.textDim, marginLeft: 4 }}>· Lv 12</span>
          </>
        )}
      </DynamicIsland>

      <div style={{ height: '100%', display: 'flex', flexDirection: 'column', paddingTop: 56 }}>
        <div style={{ flex: 1, overflow: 'auto', position: 'relative' }}>
          {route === 'dashboard' && <DashboardScreen state={state} setState={setState} openAI={openAI} navigate={navigate} showToast={showToast} user={user} profile={profile} />}
          {route === 'tasks' && <TasksScreen state={state} setState={setState} openAI={openAI} navigate={navigate} showToast={showToast} />}
          {route === 'finance' && <FinanceScreen state={state} setState={setState} navigate={navigate} showToast={showToast} />}
          {route === 'habits' && <HabitsScreen state={state} setState={setState} navigate={navigate} showToast={showToast} />}
          {route === 'goals' && <GoalsScreen state={state} setState={setState} navigate={navigate} showToast={showToast} />}
          {route === 'ai' && <AIScreen state={state} setState={setState} navigate={navigate} showToast={showToast} user={user} />}
          {route === 'calendar' && <CalendarScreen state={state} setState={setState} navigate={navigate} showToast={showToast} />}
          {route === 'more' && <MoreScreen state={state} setState={setState} navigate={navigate} showToast={showToast} user={user} onLogout={handleLogout} syncStatus={syncStatus} profile={profile} themePref={themePref} onChangeTheme={applyAndPersistTheme} />}
          {route === 'admin' && <AdminScreen navigate={navigate} showToast={showToast} />}
          {route === 'vault' && <VaultScreen state={state} setState={setState} navigate={navigate} showToast={showToast} />}
          {route === 'profile' && <ProfileScreen state={state} navigate={navigate} />}
          {route === 'achievements' && <AchievementsScreen state={state} navigate={navigate} />}
          {route === 'plans' && <PlansScreen navigate={navigate} showToast={showToast} user={user} profile={profile} />}
          {route === 'notifications' && <NotificationsScreen navigate={navigate} showToast={showToast} />}
        </div>
      </div>

      <BottomNav active={bottomTab} onChange={navigate} />
      <Toast text={toast.text} icon={toast.icon} visible={toast.visible} />
      <HomeIndicator light />
    </PhoneShell>
  );
};

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