// ============================================================
// App principal: layout + router por rol
// ============================================================
const STORAGE_KEY = window.APP_CONFIG.LOCAL_STORAGE_KEYS.APP_STATE;

const loadState = () => {
  try {
    const raw = localStorage.getItem(STORAGE_KEY);
    if (raw) return JSON.parse(raw);
  } catch (e) {}

  return null;
};

const saveState = (state) => {
  try {
    localStorage.setItem(STORAGE_KEY, JSON.stringify(state));
  } catch (e) {}
};

const App = () => {
  const stored = loadState();

  const [currentUser, setCurrentUser] = useState(null);
  const [authState, setAuthState] = useState('initializing');
  const [authRetry, setAuthRetry] = useState(0);
  const [screen, setScreen] = useState(stored?.screen || 'dashboard');

  const [libros, setLibros] = useState(() =>
    window.APP_CONFIG.AUTH.MODE === 'server'
      ? []
      : (stored?.libros || APP_DATA.LIBROS)
  );

  const [usuarios, setUsuarios] = useState(
    stored?.usuarios || APP_DATA.USUARIOS
  );

  const [selectedBook, setSelectedBook] = useState(null);

  // Sincroniza usuarios con APP_DATA para conservar referencias locales.
  useEffect(() => {
    APP_DATA.USUARIOS = usuarios;
  }, [usuarios]);

  /**
   * Define la pantalla inicial de acuerdo con el rol.
   *
   * El administrador debe entrar siempre al Dashboard.
   * El orden de las validaciones es importante para usuarios con varios roles.
   */
  const initialScreenForUser = (user) => {
    if (window.authMapper.hasRole(user, 'administrator')) {
      return 'dashboard';
    }

    if (window.authMapper.hasRole(user, 'supervisor')) {
      return 'supervisor';
    }

    if (window.authMapper.hasRole(user, 'digitizer')) {
      return 'digitalizacion';
    }

    if (window.authMapper.hasRole(user, 'editor')) {
      return 'edicion';
    }

    if (window.authMapper.hasRole(user, 'quality')) {
      return 'cc';
    }

    if (window.authMapper.hasRole(user, 'converter')) {
      return 'conversion';
    }

    return 'dashboard';
  };

  useEffect(() => {
    let active = true;

    const restoreSession = async () => {
      setAuthState('initializing');

      try {
        const initialized = await window.persistenceAdapter.initialize();

        if (!active) return;

        if (
          (initialized.mode === 'server' && !initialized.apiAvailable) ||
          (
            initialized.mode === 'local_demo' &&
            !initialized.localDemoAllowed
          )
        ) {
          setCurrentUser(null);
          setAuthState('unavailable');
          return;
        }

        if (!window.APP_CONFIG.AUTH.SESSION_CHECK_ON_START) {
          setAuthState('unauthenticated');
          return;
        }

        const session = await window.persistenceAdapter.getSession();

        if (!active) return;

        if (session.authenticated && session.user) {
          setCurrentUser(session.user);
          setScreen(initialScreenForUser(session.user));
          setAuthState('authenticated');
        } else {
          setCurrentUser(null);
          setAuthState('unauthenticated');
        }
      } catch (error) {
        if (!active) return;

        setCurrentUser(null);
        setAuthState('unavailable');
      }
    };

    restoreSession();

    return () => {
      active = false;
    };
  }, [authRetry]);

  // Persistencia exclusiva para modo de demostración local.
  useEffect(() => {
    if (
      window.persistenceAdapter.mode !== 'local_demo' ||
      !window.APP_CONFIG.AUTH.ALLOW_LOCAL_DEMO
    ) {
      return;
    }

    const state = {
      screen,
      libros,
      usuarios,
      currentUser,
    };

    saveState(state);
  }, [currentUser, screen, libros, usuarios]);

  const onLogin = (user) => {
    setCurrentUser(user);
    setScreen(initialScreenForUser(user));
    setAuthState('authenticated');
  };

  const clearVisualSession = () => {
    setCurrentUser(null);
    setSelectedBook(null);
    setScreen('dashboard');
    setAuthState('unauthenticated');
  };

  const onSessionExpired = () => {
    clearVisualSession();
  };

  const onLogout = async () => {
    try {
      await window.persistenceAdapter.logout();
    } catch (error) {
      console.warn(
        'No fue posible confirmar el cierre de sesión con el servidor.'
      );
    } finally {
      clearVisualSession();
    }
  };

  const updateLibro = (cons, patch) => {
    setLibros((previous) =>
      previous.map((libro) =>
        libro.cons === cons
          ? { ...libro, ...patch }
          : libro
      )
    );
  };

  const updateUsuario = (id, data) => {
    setUsuarios((previous) =>
      previous.map((usuario) =>
        usuario.id === id
          ? { ...usuario, ...data }
          : usuario
      )
    );

    if (
      currentUser?.authSource === 'local_demo' &&
      currentUser.id === id
    ) {
      setCurrentUser((user) =>
        window.authMapper.normalizeAuthUser(
          { ...user, ...data },
          'local_demo'
        )
      );
    }
  };

  const createUsuario = (data) => {
    if (usuarios.find((usuario) => usuario.id === data.id)) {
      alert(
        `El usuario "${data.id}" ya existe. Elige otro nombre.`
      );
      return;
    }

    setUsuarios((previous) => [
      ...previous,
      { ...data },
    ]);
  };

  const deleteUsuario = (id) => {
    setUsuarios((previous) =>
      previous.filter((usuario) => usuario.id !== id)
    );
  };

  if (authState !== 'authenticated' || !currentUser) {
    return (
      <Login
        onLogin={onLogin}
        authStatus={authState}
        onRetry={() =>
          setAuthRetry((value) => value + 1)
        }
      />
    );
  }

  const isSupervisor = window.authMapper.hasAnyRole(
    currentUser,
    ['administrator', 'supervisor']
  );

  const isServerMode =
    window.APP_CONFIG.AUTH.MODE === 'server';

  // Pantallas disponibles de acuerdo con el rol.
  const navItems = [];

  navItems.push({
    key: 'dashboard',
    label: 'Dashboard',
    icon: 'dashboard',
  });

  if (isSupervisor) {
    navItems.push({
      key: 'supervisor',
      label: 'Asignación FIFO',
      icon: 'fifo',
    });
  }

  if (
    isSupervisor ||
    window.authMapper.hasRole(currentUser, 'digitizer')
  ) {
    navItems.push({
      key: 'digitalizacion',
      label: 'Digitalización',
      icon: 'camera',
    });
  }

  if (
    isSupervisor ||
    window.authMapper.hasRole(currentUser, 'editor')
  ) {
    navItems.push({
      key: 'edicion',
      label: 'Edición',
      icon: 'edit',
    });
  }

  if (
    isSupervisor ||
    window.authMapper.hasRole(currentUser, 'quality')
  ) {
    navItems.push({
      key: 'cc',
      label: 'Control de Calidad',
      icon: 'check_shield',
    });
  }

  if (
    isSupervisor ||
    window.authMapper.hasAnyRole(
      currentUser,
      ['digitizer', 'editor', 'quality']
    )
  ) {
    navItems.push({
      key: 'buzon',
      label: 'Buzón de correcciones',
      icon: 'alert',
    });
  }

  if (
    window.authMapper.hasAnyRole(
      currentUser,
      ['administrator', 'supervisor', 'converter']
    )
  ) {
    navItems.push({
      key: 'conversion',
      label: 'Conversión',
      icon: 'convert',
    });
  }

  navItems.push({
    key: 'catalogo',
    label: 'Catálogo',
    icon: 'library',
  });

  if (isSupervisor) {
    navItems.push({
      key: 'rutas',
      label: 'Rutas de imágenes',
      icon: 'settings',
    });

    navItems.push({
      key: 'publicacion',
      label: 'Publicar BD',
      icon: 'convert',
    });

    navItems.push({
      key: 'usuarios',
      label: 'Usuarios y perfiles',
      icon: 'users',
    });

    navItems.push({
      key: 'nuevo_proyecto',
      label: 'Nuevo Proyecto',
      icon: 'plus_circle',
    });
  }

  // Contadores del menú.
  const counts = {
    supervisor: libros.filter(
      (libro) => libro.estatus === 'digitalizado'
    ).length,

    digitalizacion: isServerMode
      ? 0
      : libros.filter(
          (libro) =>
            (
              libro.estatus === 'en_digitalizacion' &&
              libro.digitalizadoPor === currentUser.id
            ) ||
            libro.estatus === 'nuevo'
        ).length,

    edicion: isServerMode
      ? 0
      : libros.filter(
          (libro) =>
            libro.estatus === 'en_edicion' &&
            libro.editadoPor === currentUser.id
        ).length,

    cc: libros.filter(
      (libro) => libro.estatus === 'editado'
    ).length,

    buzon: 0,

    conversion: libros.filter(
      (libro) =>
        ['aceptado', 'en_conversion'].includes(
          libro.estatus
        )
    ).length,
  };

  const screenTitle = {
    dashboard: 'Dashboard estadístico',
    supervisor: 'Asignación FIFO · Supervisor',
    digitalizacion: 'Digitalización de libros',
    edicion: 'Edición de imágenes',
    cc: 'Control de calidad',
    buzon: 'Buzón de correcciones',
    conversion: 'Conversión de formatos',
    catalogo: 'Catálogo de libros',
    rutas: 'Rutas de imágenes',
    publicacion: 'Publicación de base de datos',
    usuarios: 'Gestión de usuarios y perfiles',
    nuevo_proyecto: 'Alta de nuevo proyecto',
  }[screen];

  const screenSub = {
    dashboard:
      'Meta 409 libros · 70,000 imágenes · Deadline 12 sep 2026',

    supervisor:
      'Asigna libros digitalizados a editores respetando el orden de entrada',

    digitalizacion:
      'Procesa libros físicos y registra imágenes resultantes',

    edicion:
      'Edita imágenes y registra productividad por corte horario',

    cc:
      'Revisa la calidad de la edición y decide aceptar o rechazar',

    buzon:
      'Consulta y atiende observaciones asignadas',

    conversion:
      'Genera los formatos JPG, TIFF, PDF y EPUB',

    catalogo:
      'Base de datos completa del proyecto',

    nuevo_proyecto:
      'Crear un nuevo proyecto con las mismas características',
  }[screen];

  return (
    <div
      className="app-shell"
      data-screen-label={`${screen}`}
    >
      {/* Sidebar */}
      <div className="sidebar">
        <div className="sidebar-brand">
          <div className="sidebar-brand-title">
            Digitalización
            <br />
            de Libros
          </div>

          <div className="sidebar-brand-sub">
            Control 2026
          </div>
        </div>

        <div className="sidebar-section">
          General
        </div>

        {navItems
          .filter((item) =>
            ['dashboard', 'supervisor'].includes(item.key)
          )
          .map((item) => (
            <div
              key={item.key}
              className={
                `nav-item ${
                  screen === item.key ? 'active' : ''
                }`
              }
              onClick={() => setScreen(item.key)}
            >
              <Icon
                name={item.icon}
                size={16}
                style={{ flexShrink: 0 }}
              />

              <span>{item.label}</span>

              {counts[item.key] > 0 && (
                <span className="nav-item-count">
                  {counts[item.key]}
                </span>
              )}
            </div>
          ))}

        <div className="sidebar-section">
          Mis procesos
        </div>

        {navItems
          .filter((item) =>
            [
              'digitalizacion',
              'edicion',
              'cc',
              'buzon',
              'conversion',
            ].includes(item.key)
          )
          .map((item) => (
            <div
              key={item.key}
              className={
                `nav-item ${
                  screen === item.key ? 'active' : ''
                }`
              }
              onClick={() => setScreen(item.key)}
            >
              <Icon
                name={item.icon}
                size={16}
                style={{ flexShrink: 0 }}
              />

              <span>{item.label}</span>

              {counts[item.key] > 0 && (
                <span className="nav-item-count">
                  {counts[item.key]}
                </span>
              )}
            </div>
          ))}

        <div className="sidebar-section">
          Administración
        </div>

        {navItems
          .filter((item) =>
            [
              'catalogo',
              'rutas',
              'publicacion',
              'usuarios',
              'nuevo_proyecto',
            ].includes(item.key)
          )
          .map((item) => (
            <div
              key={item.key}
              className={
                `nav-item ${
                  screen === item.key ? 'active' : ''
                }`
              }
              onClick={() => setScreen(item.key)}
            >
              <Icon
                name={item.icon}
                size={16}
                style={{ flexShrink: 0 }}
              />

              <span>{item.label}</span>
            </div>
          ))}

        <div className="sidebar-user">
          <Avatar user={currentUser} />

          <div className="sidebar-user-info">
            <div className="sidebar-user-name">
              {currentUser.nombre}
            </div>

            <div className="sidebar-user-role">
              {window.authMapper.hasRole(
                currentUser,
                'administrator'
              )
                ? 'Administrador'
                : isSupervisor
                  ? 'Supervisor'
                  : currentUser.roles.length > 2
                    ? 'Multi-rol'
                    : window.authMapper.roleLabel(
                        currentUser.roles[0]
                      )}
            </div>
          </div>

          <button
            className="sidebar-logout"
            onClick={onLogout}
            data-tooltip="Cerrar sesión"
          >
            <Icon
              name="logout"
              size={16}
            />
          </button>
        </div>
      </div>

      {/* Contenido principal */}
      <div className="main">
        <div className="topbar">
          <div>
            <div className="topbar-subtitle">
              {APP_DATA.PROYECTO.nombre}
            </div>

            <div className="topbar-title">
              {screenTitle}
            </div>
          </div>

          <div className="topbar-actions">
            <div className="text-sm text-2 text-mono">
              {new Date().toLocaleDateString(
                'es-MX',
                {
                  weekday: 'long',
                  day: 'numeric',
                  month: 'long',
                  year: 'numeric',
                }
              )}
            </div>
          </div>
        </div>

        <div
          className="content"
          data-screen-label={screen}
        >
          {screen === 'dashboard' && (
            <Dashboard
              onSelectBook={setSelectedBook}
              onSessionExpired={onSessionExpired}
            />
          )}

          {screen === 'supervisor' && (
            <Supervisor
              libros={libros}
              currentUser={currentUser}
              onUpdate={updateLibro}
              onSelectBook={setSelectedBook}
              onSessionExpired={onSessionExpired}
            />
          )}

          {screen === 'digitalizacion' && (
            <Digitalizacion
              libros={libros}
              currentUser={currentUser}
              onUpdate={updateLibro}
              onSelectBook={setSelectedBook}
              onSessionExpired={onSessionExpired}
            />
          )}

          {screen === 'edicion' && (
            <Edicion
              libros={libros}
              currentUser={currentUser}
              onUpdate={updateLibro}
              onSelectBook={setSelectedBook}
              onSessionExpired={onSessionExpired}
            />
          )}

          {screen === 'cc' && (
            <ControlCalidad
              libros={libros}
              currentUser={currentUser}
              onUpdate={updateLibro}
              onSelectBook={setSelectedBook}
              onSessionExpired={onSessionExpired}
            />
          )}

          {screen === 'buzon' && (
            <BuzonCorrecciones
              currentUser={currentUser}
              onSessionExpired={onSessionExpired}
            />
          )}

          {screen === 'conversion' && (
            <Conversion
              libros={libros}
              currentUser={currentUser}
              onUpdate={updateLibro}
              onSelectBook={setSelectedBook}
              onSessionExpired={onSessionExpired}
            />
          )}

          {screen === 'catalogo' && (
            <Catalogo
              libros={libros}
              onSelectBook={setSelectedBook}
              onSessionExpired={onSessionExpired}
            />
          )}

          {screen === 'rutas' && (
            <Rutas
              libros={libros}
              onUpdate={updateLibro}
              currentUser={currentUser}
              onSessionExpired={onSessionExpired}
            />
          )}

          {screen === 'publicacion' && (
            <Publicacion
              libros={libros}
            />
          )}

          {screen === 'usuarios' && (
            <GestionUsuarios
              usuarios={usuarios}
              onUpdate={updateUsuario}
              onCreate={createUsuario}
              onDelete={deleteUsuario}
            />
          )}

          {screen === 'nuevo_proyecto' && (
            <NuevoProyecto
              onCreate={() => {}}
              onClose={() =>
                setScreen('dashboard')
              }
            />
          )}
        </div>
      </div>

      <BookDetail
        libro={selectedBook}
        onClose={() => setSelectedBook(null)}
      />
    </div>
  );
};

// Montar aplicación.
ReactDOM
  .createRoot(document.getElementById('root'))
  .render(<App />);