// INDISA Enterprise OS — App router
const { useState: uS, useEffect: uE, useMemo: uM } = React;

// Persistent state hook — syncs with localStorage and, when configured, saves data to Supabase.
const LS_PREFIX = "indisa_v1_";
function usePersistentState(key, initial) {
  const [value, setValue] = uS(() => {
    try {
      const raw = localStorage.getItem(LS_PREFIX + key);
      if (raw != null) return JSON.parse(raw);
    } catch (e) {}
    return initial;
  });
  const [supabaseLoaded, setSupabaseLoaded] = uS(false);

  uE(() => {
    try { localStorage.setItem(LS_PREFIX + key, JSON.stringify(value)); } catch (e) {}
  }, [key, value]);

  uE(() => {
    let cancelled = false;
    async function loadRemote() {
      const state = window.SUPABASE_STATE;
      if (!state || !window.SUPABASE?.client) {
        setSupabaseLoaded(true);
        return;
      }
      try {
        const remoteValue = await state.load(key, initial);
        // Only overwrite if Supabase actually has data (null means no remote record yet)
        if (!cancelled && remoteValue !== null && remoteValue !== undefined) {
          setValue(remoteValue);
        }
      } catch (error) {
        console.warn("Supabase state load failed for", key, error);
      } finally {
        if (!cancelled) setSupabaseLoaded(true);
      }
    }
    loadRemote();
    return () => { cancelled = true; };
  }, [key, initial]);

  uE(() => {
    if (!supabaseLoaded) return;
    const state = window.SUPABASE_STATE;
    if (!state || !window.SUPABASE?.client) return;
    state.save(key, value).catch((error) => {
      console.warn("Supabase state save failed for", key, error);
    });
  }, [key, value, supabaseLoaded]);

  return [value, setValue];
}

function App() {
  const D = window.INDISA_DATA;
  // Session — restored from localStorage on mount; cleared on logout or Supabase expiry
  const [session, setSession] = uS(() => {
    try {
      const raw = localStorage.getItem(LS_PREFIX + "session");
      if (raw) {
        const s = JSON.parse(raw);
        if (s && s.email && s.role) return s;
      }
    } catch (e) {}
    return null;
  });
  const [view, setView] = uS("dashboard");
  const [deptScope, setDeptScope] = uS(null);
  const [toast, setToast] = uS(null);
  // Persisted UI prefs + data
  const [theme, setTheme] = usePersistentState("theme", "light");
  const [kpis, setKpis] = usePersistentState("kpis", D.INITIAL_KPIS);
  const [projects, setProjects] = usePersistentState("projects", D.INITIAL_PROJECTS);
  const [poa, setPoa] = usePersistentState("poa", D.INITIAL_POA);
  const [codes, setCodes] = usePersistentState("codes", D.INITIAL_CODES);
  const [audit, setAudit] = usePersistentState("audit", D.INITIAL_AUDIT);
  const [tasks, setTasks] = usePersistentState("tasks", D.INITIAL_TASKS || []);
  const [files, setFiles] = usePersistentState("files", D.INITIAL_FILES || []);
  const [events, setEvents] = usePersistentState("events", D.INITIAL_EVENTS || []);
  const [departments, setDepartments] = usePersistentState("departments", D.DEPARTMENTS);
  const [kpiSemanal, setKpiSemanal] = usePersistentState("kpiSemanal", D.INITIAL_KPI_SEMANAL);
  // Users always loaded fresh from profiles table — never persisted to app_state
  const [users, setUsers] = uS(() => {
    try { localStorage.removeItem("indisa_v1_users"); } catch (e) {}
    return {};
  });

  // Keep window.INDISA_DATA in sync with departments state so other modules see deletions
  uE(() => {
    window.INDISA_DATA.DEPARTMENTS = departments;
    window.INDISA_DATA.DEPT_BY_ID = Object.fromEntries(departments.map(d => [d.id, d]));
  }, [departments]);

  uE(() => { document.documentElement.dataset.theme = theme; }, [theme]);

  // Expose scope-switcher to nested components
  uE(() => { window.__indisaScopeTo = (d) => { setDeptScope(d); setView("dashboard"); }; }, []);

  uE(() => {
    let cancelled = false;
    let subscription = null;

    async function initAuth() {
      if (!window.SUPABASE_AUTH) return;
      const allProfiles = await window.SUPABASE_AUTH.loadAllProfiles?.() || [];
      if (!cancelled && allProfiles.length > 0) {
        const profileMap = {};
        allProfiles.forEach(p => { profileMap[p.email.toLowerCase()] = p; });
        setUsers(profileMap);
      }
      // When Supabase is active, validate the stored session against it.
      // If the Supabase token expired, force re-login to keep both in sync.
      if (window.SUPABASE?.client && !cancelled) {
        const supaSession = await window.SUPABASE_AUTH.getSession?.();
        if (!cancelled && !supaSession) {
          try { localStorage.removeItem(LS_PREFIX + "session"); } catch (_) {}
          setSession(null);
        }
      }
      subscription = window.SUPABASE_AUTH.onAuthStateChange((event, supaSession) => {
        if (!supaSession?.user) {
          try { localStorage.removeItem(LS_PREFIX + "session"); } catch (_) {}
          setSession(null);
        }
      });
    }

    initAuth();

    return () => {
      cancelled = true;
      if (subscription?.unsubscribe) subscription.unsubscribe();
    };
  }, []);

  function showToast(msg) {
    setToast(msg);
    setTimeout(() => setToast(null), 2200);
  }

  function addAudit({ action, user, dept, level }) {
    const now = "2026-05-14 " + new Date().toLocaleTimeString("en-GB", { hour12: false, hour: "2-digit", minute: "2-digit" });
    setAudit(prev => [{ ts: now, action, user, dept, level: level || "info" }, ...prev]);
  }

  function login(s, codeUsed) {
    try { localStorage.setItem(LS_PREFIX + "session", JSON.stringify(s)); } catch (e) {}
    setSession(s);
    if (codeUsed) {
      // First-time login with code: register user and increment uses
      setCodes(prev => prev.map(c => c.code === codeUsed ? { ...c, uses: c.uses + 1 } : c));
    }
    setUsers(prev => ({ ...prev, [s.email.toLowerCase()]: {
      email: s.email,
      role: s.role,
      dept: s.dept,
      deptName: s.deptName,
      name: s.name,
      code: s.code || codeUsed,
      avatar_color: s.avatar_color || prev[s.email.toLowerCase()]?.avatar_color || "#5E66FF",
      registeredAt: "2026-05-14",
    }}));
    setDeptScope(null);
    setView("dashboard");
  }

  function logout() {
    addAudit({ action: "Cierre de sesión", user: session.name, dept: session.dept, level: "info" });
    try { localStorage.removeItem(LS_PREFIX + "session"); } catch (e) {}
    setSession(null);
    window.SUPABASE_AUTH?.signOut?.().catch(() => {});
  }


  if (!session) {
    return <Auth codes={codes} users={users} onLogin={login} addAudit={addAudit}/>;
  }

  const role = session.role;
  const canSee = {
    dashboard: true,
    kpis: true,
    projects: true,
    tasks: true,
    poa: true,
    calendar: true,
    files: true,
    departments: role === "owner",
    org: true,
    codes: role !== "viewer",
    audit: role !== "viewer",
    profile: true,
  };
  const effView = canSee[view] ? view : "dashboard";

  return (
    <Shell
      session={session} view={effView} setView={setView}
      deptScope={deptScope} setDeptScope={setDeptScope}
      theme={theme} setTheme={setTheme}
      onLogout={logout} toast={toast}
      departments={departments}
      profileColor={users[session.email.toLowerCase()]?.avatarColor}
      searchData={{ kpis, projects, tasks, users, poa, files }}
      audit={audit}
    >
      {effView === "dashboard" && <Dashboard session={session} deptScope={deptScope} kpis={kpis} setKpis={setKpis} projects={projects} addAudit={addAudit} showToast={showToast} setView={setView}/>}
      {effView === "kpis" && <KPIPage session={session} deptScope={deptScope} setDeptScope={setDeptScope} kpis={kpis} setKpis={setKpis} kpiSemanal={kpiSemanal} setKpiSemanal={setKpiSemanal} addAudit={addAudit} showToast={showToast}/>}
      {effView === "projects" && <ProjectsPage session={session} deptScope={deptScope} projects={projects} setProjects={setProjects} tasks={tasks} addAudit={addAudit} showToast={showToast}/>}
      {effView === "tasks" && <TasksPage session={session} deptScope={deptScope} tasks={tasks} setTasks={setTasks} projects={projects} addAudit={addAudit} showToast={showToast}/>}
      {effView === "poa" && <POAPage session={session} deptScope={deptScope} poa={poa} setPoa={setPoa} addAudit={addAudit} showToast={showToast}/>}
      {effView === "calendar" && <CalendarPage session={session} deptScope={deptScope} projects={projects} setProjects={setProjects} tasks={tasks} setTasks={setTasks} events={events} setEvents={setEvents} addAudit={addAudit} showToast={showToast}/>}
      {effView === "files" && <FilesPage session={session} deptScope={deptScope} files={files} setFiles={setFiles} addAudit={addAudit} showToast={showToast}/>}
      {effView === "departments" && <Departments session={session} kpis={kpis} projects={projects} departments={departments} setDepartments={setDepartments} setView={setView} setDeptScope={setDeptScope} showToast={showToast} addAudit={addAudit}/>}
      {effView === "org" && <OrgChart session={session} users={users} onSelectDept={(d) => { if (role === "owner") setDeptScope(d); }}/>}
      {effView === "codes" && <CodesPage session={session} codes={codes} setCodes={setCodes} addAudit={addAudit} showToast={showToast}/>}
      {effView === "audit" && <AuditPage session={session} audit={audit}/>}
      {effView === "profile" && <ProfilePage session={session} setSession={setSession} users={users} setUsers={setUsers} theme={theme} setTheme={setTheme} addAudit={addAudit} showToast={showToast}/>}
    </Shell>
  );
}

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