/* ============================================================
   EATME PORTÁL – SECURITY HELPERS
============================================================ */


/* ============================================================
   NÁHODNÝ AKTIVAČNÍ KÓD
============================================================ */

function randomCode_() {

  return String(
    Math.floor(
      100000 +
      Math.random() *
      900000
    )
  );

}



/* ============================================================
   SESSION TOKEN
============================================================ */

function randomToken_() {

  return Utilities
    .base64EncodeWebSafe(
      Utilities.computeDigest(
        Utilities.DigestAlgorithm.SHA_256,
        Utilities.getUuid() +
        ':' +
        new Date().getTime() +
        ':' +
        Math.random()
      )
    )
    .replace(
      /=+$/,
      ''
    );

}



/* ============================================================
   SHA-256
============================================================ */

function hashText_(text) {

  const bytes =
    Utilities.computeDigest(
      Utilities.DigestAlgorithm.SHA_256,
      String(
        text
      )
    );


  return bytes
    .map(
      function(byte) {

        return (
          '0' +
          (
            (
              byte < 0
                ? byte + 256
                : byte
            )
              .toString(
                16
              )
          )
        ).slice(
          -2
        );

      }
    )
    .join(
      ''
    );

}



/* ============================================================
   PASSWORD HASH

   POZOR:
   Toto je původní algoritmus.
   Neměníme jej, aby fungovala současná hesla.
============================================================ */

function passwordHash_(
  password,
  salt
) {

  const pepper =
    PropertiesService
      .getScriptProperties()
      .getProperty(
        'PASSWORD_PEPPER'
      ) ||
    '';


  let value =
    String(
      password
    ) +
    '|' +
    salt +
    '|' +
    pepper;


  for (
    let i = 0;
    i < CFG.PASSWORD_ROUNDS;
    i++
  ) {

    value =
      hashText_(
        value +
        '|' +
        i
      );

  }


  return value;

}



/* ============================================================
   VALIDACE HESLA
============================================================ */

function validatePassword_(password) {

  const value =
    String(
      password ||
      ''
    );


  if (
    value.length <
    10
  ) {

    throw new Error(
      'Heslo musí mít alespoň 10 znaků.'
    );

  }


  if (
    !/[A-Za-z]/.test(
      value
    ) ||
    !/[0-9]/.test(
      value
    )
  ) {

    throw new Error(
      'Heslo musí obsahovat písmeno a číslo.'
    );

  }

}



/* ============================================================
   OVĚŘENÍ UŽIVATELE

   Optimalizace:
   už při každém requestu NEZAPISUJEME last_seen_at.
============================================================ */

function requireUser_(
  token,
  roles
) {

  const tokenHash =
    hashText_(
      String(
        token ||
        ''
      )
    );


  const session =
    findOne_(
      CFG.SHEETS.SESSIONS,
      function(row) {

        return (

          String(
            row.token_hash
          ) ===
            tokenHash &&

          new Date(
            row.expires_at
          ).getTime() >
            Date.now()

        );

      }
    );


  if (
    !session
  ) {

    throw new Error(
      'Přihlášení vypršelo. Přihlas se znovu.'
    );

  }


  const user =
    findOne_(
      CFG.SHEETS.USERS,
      function(row) {

        return (
          String(
            row.user_id
          ) ===
          String(
            session.user_id
          )
        );

      }
    );


  if (
    !user ||
    !(
      user.active ===
        true ||

      String(
        user.active
      ).toUpperCase() ===
        'TRUE'
    )
  ) {

    throw new Error(
      'Účet není aktivní.'
    );

  }


  if (
    roles &&
    roles.length &&
    !roles.includes(
      String(
        user.role
      )
    )
  ) {

    throw new Error(
      'Nemáš oprávnění.'
    );

  }


  /*
   * PŮVODNĚ ZDE BYLO:
   *
   * updateBy_(
   *   CFG.SHEETS.SESSIONS,
   *   'session_id',
   *   session.session_id,
   *   {last_seen_at:now_()}
   * );
   *
   * To způsobovalo zápis do Google Sheets při téměř
   * každém kliknutí v aplikaci.
   */


  return user;

}



/* ============================================================
   AUDIT
============================================================ */

function audit_(
  userId,
  action,
  entityType,
  entityId,
  oldValue,
  newValue
) {

  append_(
    CFG.SHEETS.AUDIT_LOG,
    {

      audit_id:
        uuid_(
          'AUD'
        ),

      user_id:
        userId ||
        'SYSTEM',

      action:
        action,

      entity_type:
        entityType ||
        '',

      entity_id:
        entityId ||
        '',

      old_value:
        json_(
          oldValue
        ),

      new_value:
        json_(
          newValue
        ),

      created_at:
        now_()

    }
  );

}