const bcrypt =
  require("bcryptjs");

const {
  pool
} = require("../config/db");

const {
  writeAdminAuditLog
} = require(
  "../services/adminAuditService"
);

/* =========================================================
   CONSTANTS
   ========================================================= */

const allowedRoles =
  new Set([
    "super_admin",
    "hr_admin",
    "hr_reviewer",
    "viewer"
  ]);

const allowedStatuses =
  new Set([
    "active",
    "inactive"
  ]);

const passwordSaltRounds = 12;

/* =========================================================
   GENERAL HELPERS
   ========================================================= */

const normalizePositiveInteger = (
  value,
  fallback = 0,
  maximum =
    Number.MAX_SAFE_INTEGER
) => {
  const number =
    Number(value);

  if (
    !Number.isInteger(number) ||
    number < 1
  ) {
    return fallback;
  }

  return Math.min(
    number,
    maximum
  );
};

const normalizeText = (
  value,
  maximumLength = 150
) => {
  return String(value || "")
    .trim()
    .slice(
      0,
      maximumLength
    );
};

const normalizeUsername = (
  value
) => {
  return normalizeText(
    value,
    80
  ).toLowerCase();
};

const normalizeEmail = (
  value
) => {
  return normalizeText(
    value,
    150
  ).toLowerCase();
};

const toNumber = (
  value
) => {
  const number =
    Number(value);

  return Number.isFinite(number)
    ? number
    : 0;
};

const getRequestIp = (
  request
) => {
  return (
    request.ip ||
    request.socket
      ?.remoteAddress ||
    null
  );
};

const getUserAgent = (
  request
) => {
  const userAgent =
    request.get(
      "user-agent"
    );

  return userAgent
    ? userAgent.slice(
        0,
        500
      )
    : null;
};

const isValidEmail = (
  value
) => {
  return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(
    value
  );
};

const isValidUsername = (
  value
) => {
  return /^[a-z0-9._-]{3,80}$/.test(
    value
  );
};

const validatePassword = (
  password
) => {
  const errors = [];

  if (password.length < 12) {
    errors.push(
      "Password must contain at least 12 characters."
    );
  }

  if (
    !/[a-z]/.test(
      password
    )
  ) {
    errors.push(
      "Password must contain a lowercase letter."
    );
  }

  if (
    !/[A-Z]/.test(
      password
    )
  ) {
    errors.push(
      "Password must contain an uppercase letter."
    );
  }

  if (
    !/[0-9]/.test(
      password
    )
  ) {
    errors.push(
      "Password must contain a number."
    );
  }

  if (
    !/[^A-Za-z0-9]/.test(
      password
    )
  ) {
    errors.push(
      "Password must contain a special character."
    );
  }

  return errors;
};

const sendDevelopmentError = (
  response,
  error,
  fallbackMessage
) => {
  return response.status(500).json({
    success: false,

    message:
      process.env.NODE_ENV ===
      "development"
        ? error.sqlMessage ||
          error.message ||
          fallbackMessage
        : fallbackMessage
  });
};

const mapAdminUser = (
  user
) => {
  return {
    ...user,

    id:
      toNumber(
        user.id
      ),

    active_assignments:
      toNumber(
        user
          .active_assignments
      ),

    total_assignments:
      toNumber(
        user
          .total_assignments
      )
  };
};

/* =========================================================
   VALIDATION
   ========================================================= */

const validateUserPayload = ({
  body,
  requirePassword = false
}) => {
  const fullName =
    normalizeText(
      body?.full_name,
      150
    );

  const username =
    normalizeUsername(
      body?.username
    );

  const email =
    normalizeEmail(
      body?.email
    );

  const role =
    normalizeText(
      body?.role,
      40
    );

  const status =
    normalizeText(
      body?.status ||
      "active",
      20
    );

  const password =
    String(
      body?.password ||
      ""
    );

  const errors = {};

  if (fullName.length < 3) {
    errors.full_name =
      "Enter the administrator's full name.";
  }

  if (
    !isValidUsername(
      username
    )
  ) {
    errors.username =
      "Use 3–80 letters, numbers, dots, underscores or hyphens.";
  }

  if (
    !isValidEmail(
      email
    )
  ) {
    errors.email =
      "Enter a valid email address.";
  }

  if (
    !allowedRoles.has(
      role
    )
  ) {
    errors.role =
      "Select a valid administrator role.";
  }

  if (
    !allowedStatuses.has(
      status
    )
  ) {
    errors.status =
      "Select a valid account status.";
  }

  if (
    requirePassword ||
    password
  ) {
    const passwordErrors =
      validatePassword(
        password
      );

    if (
      passwordErrors.length >
      0
    ) {
      errors.password =
        passwordErrors.join(
          " "
        );
    }
  }

  return {
    values: {
      fullName,
      username,
      email,
      role,
      status,
      password
    },

    errors
  };
};

/* =========================================================
   CHECK DUPLICATE USERNAME OR EMAIL
   ========================================================= */

const findDuplicateUser =
  async ({
    connection,
    username,
    email,
    excludeUserId = null
  }) => {
    const parameters = [
      username,
      email
    ];

    let exclusionClause =
      "";

    if (excludeUserId) {
      exclusionClause =
        "AND id <> ?";

      parameters.push(
        excludeUserId
      );
    }

    const [
      duplicateRows
    ] = await connection.query(
      `
        SELECT
          id,
          username,
          email

        FROM admin_users

        WHERE
          (
            LOWER(username) = ?
            OR LOWER(email) = ?
          )

          ${exclusionClause}

        LIMIT 1
      `,
      parameters
    );

    return (
      duplicateRows[0] ||
      null
    );
  };

/* =========================================================
   LAST SUPER ADMIN PROTECTION
   ========================================================= */

const countOtherActiveSuperAdmins =
  async (
    connection,
    excludedAdminId
  ) => {
    const [
      rows
    ] = await connection.query(
      `
        SELECT
          COUNT(*) AS total

        FROM admin_users

        WHERE
          role =
            'super_admin'

          AND status =
            'active'

          AND id <> ?
      `,
      [
        excludedAdminId
      ]
    );

    return toNumber(
      rows[0]?.total
    );
  };

/* =========================================================
   ACTIVE ASSIGNMENT COUNT
   ========================================================= */

const countActiveAssignments =
  async (
    connection,
    adminUserId
  ) => {
    const [
      rows
    ] = await connection.query(
      `
        SELECT
          COUNT(*) AS total

        FROM submission_reviews

        WHERE
          assigned_to = ?

          AND review_status IN (
            'pending',
            'under_review'
          )
      `,
      [
        adminUserId
      ]
    );

    return toNumber(
      rows[0]?.total
    );
  };

/* =========================================================
   GET ADMINISTRATOR USERS
   GET /api/admin/users
   ========================================================= */

const getAdminUsers = async (
  request,
  response
) => {
  try {
    const page =
      normalizePositiveInteger(
        request.query.page,
        1,
        1000000
      );

    const limit =
      normalizePositiveInteger(
        request.query.limit,
        10,
        100
      );

    const offset =
      (page - 1) *
      limit;

    const search =
      normalizeText(
        request.query.search,
        150
      );

    const requestedRole =
      normalizeText(
        request.query.role,
        40
      );

    const requestedStatus =
      normalizeText(
        request.query.status,
        20
      );

    const role =
      allowedRoles.has(
        requestedRole
      )
        ? requestedRole
        : "";

    const status =
      allowedStatuses.has(
        requestedStatus
      )
        ? requestedStatus
        : "";

    const conditions = [
      "1 = 1"
    ];

    const parameters = [];

    if (search) {
      const searchPattern =
        `%${search}%`;

      conditions.push(
        `
          (
            au.full_name LIKE ?
            OR au.username LIKE ?
            OR au.email LIKE ?
          )
        `
      );

      parameters.push(
        searchPattern,
        searchPattern,
        searchPattern
      );
    }

    if (role) {
      conditions.push(
        "au.role = ?"
      );

      parameters.push(
        role
      );
    }

    if (status) {
      conditions.push(
        "au.status = ?"
      );

      parameters.push(
        status
      );
    }

    const whereClause =
      conditions.join(
        "\nAND "
      );

    const [
      countRows
    ] = await pool.query(
      `
        SELECT
          COUNT(*) AS total_records

        FROM admin_users au

        WHERE
          ${whereClause}
      `,
      parameters
    );

    const [
      userRows
    ] = await pool.query(
      `
        SELECT
          au.id,
          au.full_name,
          au.username,
          au.email,
          au.role,
          au.status,
          au.created_at,
          au.updated_at,

          COUNT(
            CASE
              WHEN sr.review_status
                IN (
                  'pending',
                  'under_review'
                )
                THEN 1
            END
          ) AS active_assignments,

          COUNT(sr.id)
            AS total_assignments

        FROM admin_users au

        LEFT JOIN submission_reviews sr
          ON sr.assigned_to =
            au.id

        WHERE
          ${whereClause}

        GROUP BY
          au.id,
          au.full_name,
          au.username,
          au.email,
          au.role,
          au.status,
          au.created_at,
          au.updated_at

        ORDER BY
          CASE
            WHEN au.status =
              'active'
              THEN 1

            ELSE 2
          END,

          CASE
            WHEN au.role =
              'super_admin'
              THEN 1

            WHEN au.role =
              'hr_admin'
              THEN 2

            WHEN au.role =
              'hr_reviewer'
              THEN 3

            ELSE 4
          END,

          au.full_name ASC

        LIMIT ?
        OFFSET ?
      `,
      [
        ...parameters,
        limit,
        offset
      ]
    );

    const [
      overviewRows
    ] = await pool.query(
      `
        SELECT
          COUNT(*) AS total_users,

          SUM(
            status =
              'active'
          ) AS active_users,

          SUM(
            status =
              'inactive'
          ) AS inactive_users,

          SUM(
            role =
              'super_admin'
          ) AS super_admins,

          SUM(
            role =
              'hr_admin'
          ) AS hr_admins,

          SUM(
            role =
              'hr_reviewer'
          ) AS hr_reviewers,

          SUM(
            role =
              'viewer'
          ) AS viewers

        FROM admin_users
      `
    );

    const totalRecords =
      toNumber(
        countRows[0]
          ?.total_records
      );

    const totalPages =
      totalRecords > 0
        ? Math.ceil(
            totalRecords /
            limit
          )
        : 1;

    const overview =
      overviewRows[0] ||
      {};

    return response.status(200).json({
      success: true,

      data: {
        users:
          userRows.map(
            mapAdminUser
          ),

        overview: {
          total_users:
            toNumber(
              overview
                .total_users
            ),

          active_users:
            toNumber(
              overview
                .active_users
            ),

          inactive_users:
            toNumber(
              overview
                .inactive_users
            ),

          super_admins:
            toNumber(
              overview
                .super_admins
            ),

          hr_admins:
            toNumber(
              overview
                .hr_admins
            ),

          hr_reviewers:
            toNumber(
              overview
                .hr_reviewers
            ),

          viewers:
            toNumber(
              overview
                .viewers
            )
        },

        pagination: {
          current_page:
            page,

          per_page:
            limit,

          total_records:
            totalRecords,

          total_pages:
            totalPages,

          has_previous_page:
            page > 1,

          has_next_page:
            page < totalPages
        },

        filters: {
          search,
          role,
          status
        },

        permissions: {
          can_manage_users:
            request.admin
              ?.role ===
            "super_admin"
        }
      }
    });
  } catch (error) {
    console.error(
      "Get administrator users error:",
      error
    );

    return sendDevelopmentError(
      response,
      error,
      "Unable to load administrator accounts."
    );
  }
};

/* =========================================================
   CREATE ADMINISTRATOR USER
   POST /api/admin/users
   ========================================================= */

const createAdminUser = async (
  request,
  response
) => {
  let connection = null;

  let transactionStarted =
    false;

  try {
    const {
      values,
      errors
    } = validateUserPayload({
      body:
        request.body,

      requirePassword:
        true
    });

    if (
      Object.keys(
        errors
      ).length > 0
    ) {
      return response.status(422).json({
        success: false,

        message:
          "Correct the highlighted administrator account fields.",

        errors
      });
    }

    connection =
      await pool.getConnection();

    await connection.beginTransaction();

    transactionStarted = true;

    const duplicateUser =
      await findDuplicateUser({
        connection,

        username:
          values.username,

        email:
          values.email
      });

    if (duplicateUser) {
      await connection.rollback();

      transactionStarted =
        false;

      const duplicateErrors = {};

      if (
        duplicateUser
          .username
          .toLowerCase() ===
        values.username
      ) {
        duplicateErrors.username =
          "This username is already in use.";
      }

      if (
        duplicateUser
          .email
          .toLowerCase() ===
        values.email
      ) {
        duplicateErrors.email =
          "This email address is already in use.";
      }

      return response.status(409).json({
        success: false,

        message:
          "An administrator with this username or email already exists.",

        errors:
          duplicateErrors
      });
    }

    const passwordHash =
      await bcrypt.hash(
        values.password,
        passwordSaltRounds
      );

    const [
      insertResult
    ] = await connection.query(
      `
        INSERT INTO admin_users (
          full_name,
          username,
          email,
          password_hash,
          role,
          status
        )
        VALUES (
          ?,
          ?,
          ?,
          ?,
          ?,
          ?
        )
      `,
      [
        values.fullName,
        values.username,
        values.email,
        passwordHash,
        values.role,
        values.status
      ]
    );

    const createdUserId =
      insertResult.insertId;

    await writeAdminAuditLog({
      connection,

      adminUserId:
        request.admin.id,

      action:
        "ADMIN_USER_CREATED",

      entityType:
        "admin_user",

      entityId:
        createdUserId,

      description:
        `Administrator account created for ${values.fullName}.`,

      metadata: {
        full_name:
          values.fullName,

        username:
          values.username,

        email:
          values.email,

        role:
          values.role,

        status:
          values.status
      },

      ipAddress:
        getRequestIp(
          request
        ),

      userAgent:
        getUserAgent(
          request
        )
    });

    const [
      createdRows
    ] = await connection.query(
      `
        SELECT
          id,
          full_name,
          username,
          email,
          role,
          status,
          created_at,
          updated_at

        FROM admin_users

        WHERE id = ?

        LIMIT 1
      `,
      [
        createdUserId
      ]
    );

    await connection.commit();

    transactionStarted =
      false;

    return response.status(201).json({
      success: true,

      message:
        "Administrator account created successfully.",

      data: {
        user:
          mapAdminUser({
            ...createdRows[0],

            active_assignments:
              0,

            total_assignments:
              0
          })
      }
    });
  } catch (error) {
    if (
      connection &&
      transactionStarted
    ) {
      try {
        await connection.rollback();
      } catch (
        rollbackError
      ) {
        console.error(
          "Create administrator rollback error:",
          rollbackError
        );
      }
    }

    console.error(
      "Create administrator user error:",
      error
    );

    return sendDevelopmentError(
      response,
      error,
      "Unable to create the administrator account."
    );
  } finally {
    if (connection) {
      connection.release();
    }
  }
};

/* =========================================================
   UPDATE ADMINISTRATOR USER
   PUT /api/admin/users/:adminUserId
   ========================================================= */

const updateAdminUser = async (
  request,
  response
) => {
  let connection = null;

  let transactionStarted =
    false;

  try {
    const adminUserId =
      normalizePositiveInteger(
        request.params
          .adminUserId
      );

    if (!adminUserId) {
      return response.status(422).json({
        success: false,

        message:
          "A valid administrator account is required."
      });
    }

    const {
      values,
      errors
    } = validateUserPayload({
      body:
        request.body,

      requirePassword:
        false
    });

    if (
      Object.keys(
        errors
      ).length > 0
    ) {
      return response.status(422).json({
        success: false,

        message:
          "Correct the highlighted administrator account fields.",

        errors
      });
    }

    connection =
      await pool.getConnection();

    await connection.beginTransaction();

    transactionStarted = true;

    const [
      currentRows
    ] = await connection.query(
      `
        SELECT
          id,
          full_name,
          username,
          email,
          role,
          status

        FROM admin_users

        WHERE id = ?

        LIMIT 1
        FOR UPDATE
      `,
      [
        adminUserId
      ]
    );

    const currentUser =
      currentRows[0];

    if (!currentUser) {
      await connection.rollback();

      transactionStarted =
        false;

      return response.status(404).json({
        success: false,

        message:
          "The administrator account could not be found."
      });
    }

    const changingOwnRole =
      Number(adminUserId) ===
        Number(
          request.admin.id
        ) &&
      values.role !==
        currentUser.role;

    const changingOwnStatus =
      Number(adminUserId) ===
        Number(
          request.admin.id
        ) &&
      values.status !==
        currentUser.status;

    if (
      changingOwnRole ||
      changingOwnStatus
    ) {
      await connection.rollback();

      transactionStarted =
        false;

      return response.status(409).json({
        success: false,

        message:
          "You cannot change your own role or account status."
      });
    }

    const removingActiveSuperAdmin =
      currentUser.role ===
        "super_admin" &&
      currentUser.status ===
        "active" &&
      (
        values.role !==
          "super_admin" ||
        values.status !==
          "active"
      );

    if (
      removingActiveSuperAdmin
    ) {
      const otherSuperAdmins =
        await countOtherActiveSuperAdmins(
          connection,
          adminUserId
        );

      if (
        otherSuperAdmins <
        1
      ) {
        await connection.rollback();

        transactionStarted =
          false;

        return response.status(409).json({
          success: false,

          message:
            "The last active Super Administrator cannot be deactivated or assigned another role."
        });
      }
    }

    const removesReviewAccess =
      values.status ===
        "inactive" ||
      values.role ===
        "viewer";

    if (
      removesReviewAccess
    ) {
      const activeAssignments =
        await countActiveAssignments(
          connection,
          adminUserId
        );

      if (
        activeAssignments >
        0
      ) {
        await connection.rollback();

        transactionStarted =
          false;

        return response.status(409).json({
          success: false,

          message:
            `This administrator has ${activeAssignments} active review assignment${activeAssignments === 1 ? "" : "s"}. Reassign them before changing this account.`
        });
      }
    }

    const duplicateUser =
      await findDuplicateUser({
        connection,

        username:
          values.username,

        email:
          values.email,

        excludeUserId:
          adminUserId
      });

    if (duplicateUser) {
      await connection.rollback();

      transactionStarted =
        false;

      const duplicateErrors = {};

      if (
        duplicateUser
          .username
          .toLowerCase() ===
        values.username
      ) {
        duplicateErrors.username =
          "This username is already in use.";
      }

      if (
        duplicateUser
          .email
          .toLowerCase() ===
        values.email
      ) {
        duplicateErrors.email =
          "This email address is already in use.";
      }

      return response.status(409).json({
        success: false,

        message:
          "Another administrator already uses this username or email address.",

        errors:
          duplicateErrors
      });
    }

    await connection.query(
      `
        UPDATE admin_users

        SET
          full_name = ?,
          username = ?,
          email = ?,
          role = ?,
          status = ?,
          updated_at =
            CURRENT_TIMESTAMP

        WHERE id = ?
      `,
      [
        values.fullName,
        values.username,
        values.email,
        values.role,
        values.status,
        adminUserId
      ]
    );

    const roleChanged =
      currentUser.role !==
      values.role;

    const accountDeactivated =
      currentUser.status !==
        values.status &&
      values.status ===
        "inactive";

    if (
      roleChanged ||
      accountDeactivated
    ) {
      await connection.query(
        `
          DELETE FROM admin_sessions
          WHERE admin_user_id = ?
        `,
        [
          adminUserId
        ]
      );
    }

    await writeAdminAuditLog({
      connection,

      adminUserId:
        request.admin.id,

      action:
        "ADMIN_USER_UPDATED",

      entityType:
        "admin_user",

      entityId:
        adminUserId,

      description:
        `Administrator account updated for ${values.fullName}.`,

      metadata: {
        previous: {
          full_name:
            currentUser
              .full_name,

          username:
            currentUser
              .username,

          email:
            currentUser
              .email,

          role:
            currentUser
              .role,

          status:
            currentUser
              .status
        },

        updated: {
          full_name:
            values.fullName,

          username:
            values.username,

          email:
            values.email,

          role:
            values.role,

          status:
            values.status
        }
      },

      ipAddress:
        getRequestIp(
          request
        ),

      userAgent:
        getUserAgent(
          request
        )
    });

    const [
      updatedRows
    ] = await connection.query(
      `
        SELECT
          au.id,
          au.full_name,
          au.username,
          au.email,
          au.role,
          au.status,
          au.created_at,
          au.updated_at,

          COUNT(
            CASE
              WHEN sr.review_status
                IN (
                  'pending',
                  'under_review'
                )
                THEN 1
            END
          ) AS active_assignments,

          COUNT(sr.id)
            AS total_assignments

        FROM admin_users au

        LEFT JOIN submission_reviews sr
          ON sr.assigned_to =
            au.id

        WHERE au.id = ?

        GROUP BY
          au.id,
          au.full_name,
          au.username,
          au.email,
          au.role,
          au.status,
          au.created_at,
          au.updated_at

        LIMIT 1
      `,
      [
        adminUserId
      ]
    );

    await connection.commit();

    transactionStarted =
      false;

    return response.status(200).json({
      success: true,

      message:
        "Administrator account updated successfully.",

      data: {
        user:
          mapAdminUser(
            updatedRows[0]
          )
      }
    });
  } catch (error) {
    if (
      connection &&
      transactionStarted
    ) {
      try {
        await connection.rollback();
      } catch (
        rollbackError
      ) {
        console.error(
          "Update administrator rollback error:",
          rollbackError
        );
      }
    }

    console.error(
      "Update administrator user error:",
      error
    );

    return sendDevelopmentError(
      response,
      error,
      "Unable to update the administrator account."
    );
  } finally {
    if (connection) {
      connection.release();
    }
  }
};


/* =========================================================
   UPDATE ADMINISTRATOR STATUS
   PATCH /api/admin/users/:adminUserId/status
   ========================================================= */

const updateAdminUserStatus =
  async (
    request,
    response
  ) => {
    let connection = null;
    let transactionStarted =
      false;

    try {
      const adminUserId =
        normalizePositiveInteger(
          request.params
            .adminUserId
        );

      const status =
        normalizeText(
          request.body
            ?.status,
          20
        );

      if (!adminUserId) {
        return response.status(422).json({
          success: false,

          message:
            "A valid administrator account is required."
        });
      }

      if (
        !allowedStatuses.has(
          status
        )
      ) {
        return response.status(422).json({
          success: false,

          message:
            "Select a valid administrator account status.",

          errors: {
            status:
              "Status must be active or inactive."
          }
        });
      }

      if (
        Number(
          adminUserId
        ) ===
        Number(
          request.admin.id
        )
      ) {
        return response.status(409).json({
          success: false,

          message:
            "You cannot activate or deactivate your own account."
        });
      }

      connection =
        await pool.getConnection();

      await connection.beginTransaction();

      transactionStarted = true;

      const [
        administratorRows
      ] = await connection.query(
        `
          SELECT
            id,
            full_name,
            username,
            email,
            role,
            status

          FROM admin_users

          WHERE id = ?

          LIMIT 1

          FOR UPDATE
        `,
        [
          adminUserId
        ]
      );

      const administrator =
        administratorRows[0];

      if (!administrator) {
        await connection.rollback();

        transactionStarted = false;

        return response.status(404).json({
          success: false,

          message:
            "The administrator account could not be found."
        });
      }

      if (
        administrator.status ===
        status
      ) {
        await connection.rollback();

        transactionStarted = false;

        return response.status(409).json({
          success: false,

          message:
            `This administrator account is already ${status}.`
        });
      }

      /*
       * Prevent the final active Super
       * Administrator from being deactivated.
       */
      if (
        administrator.role ===
          "super_admin" &&
        administrator.status ===
          "active" &&
        status ===
          "inactive"
      ) {
        const activeSuperAdministrators =
          await countActiveSuperAdministrators(
            connection
          );

        if (
          activeSuperAdministrators <=
          1
        ) {
          await connection.rollback();

          transactionStarted = false;

          return response.status(409).json({
            success: false,

            message:
              "The final active Super Administrator cannot be deactivated."
          });
        }
      }

      await connection.query(
        `
          UPDATE admin_users

          SET
            status = ?,
            updated_at =
              CURRENT_TIMESTAMP

          WHERE id = ?
        `,
        [
          status,
          adminUserId
        ]
      );

      /*
       * Remove active sessions when the
       * account is deactivated.
       */
      if (
        status ===
        "inactive"
      ) {
        try {
          await connection.query(
            `
              DELETE FROM admin_sessions

              WHERE admin_user_id = ?
            `,
            [
              adminUserId
            ]
          );
        } catch (
          sessionDeleteError
        ) {
          /*
           * Some versions of the project may
           * not have admin_sessions. The account
           * status update should still succeed.
           */
          if (
            sessionDeleteError.code !==
            "ER_NO_SUCH_TABLE"
          ) {
            throw sessionDeleteError;
          }
        }
      }

      await writeAdminAuditLog({
        connection,

        adminUserId:
          request.admin.id,

        action:
          status === "active"
            ? "ADMIN_USER_ACTIVATED"
            : "ADMIN_USER_DEACTIVATED",

        entityType:
          "admin_user",

        entityId:
          adminUserId,

        description:
          status === "active"
            ? `Administrator account activated for ${administrator.full_name}.`
            : `Administrator account deactivated for ${administrator.full_name}.`,

        metadata: {
          administrator_name:
            administrator.full_name,

          username:
            administrator.username,

          role:
            administrator.role,

          previous_status:
            administrator.status,

          new_status:
            status
        },

        ipAddress:
          getRequestIp(
            request
          ),

        userAgent:
          getUserAgent(
            request
          )
      });

      await connection.commit();

      transactionStarted = false;

      return response.status(200).json({
        success: true,

        message:
          status === "active"
            ? "Administrator account activated successfully."
            : "Administrator account deactivated successfully.",

        data: {
          user: {
            id:
              Number(
                administrator.id
              ),

            full_name:
              administrator.full_name,

            username:
              administrator.username,

            email:
              administrator.email,

            role:
              administrator.role,

            status
          }
        }
      });
    } catch (error) {
      if (
        connection &&
        transactionStarted
      ) {
        try {
          await connection.rollback();
        } catch (
          rollbackError
        ) {
          console.error(
            "Administrator status rollback error:",
            rollbackError
          );
        }
      }

      console.error(
        "Update administrator status error:",
        error
      );

      return sendDevelopmentError(
        response,
        error,
        "Unable to update the administrator account status."
      );
    } finally {
      if (connection) {
        connection.release();
      }
    }
  };

/* =========================================================
   RESET ADMINISTRATOR PASSWORD
   PATCH /api/admin/users/:adminUserId/reset-password
   ========================================================= */

const resetAdminUserPassword =
  async (
    request,
    response
  ) => {
    let connection = null;

    let transactionStarted =
      false;

    try {
      const adminUserId =
        normalizePositiveInteger(
          request.params
            .adminUserId
        );

      const password =
        String(
          request.body
            ?.password ||
          ""
        );

      if (!adminUserId) {
        return response.status(422).json({
          success: false,

          message:
            "A valid administrator account is required."
        });
      }

      const passwordErrors =
        validatePassword(
          password
        );

      if (
        passwordErrors.length >
        0
      ) {
        return response.status(422).json({
          success: false,

          message:
            "The new password does not meet the security requirements.",

          errors: {
            password:
              passwordErrors.join(
                " "
              )
          }
        });
      }

      connection =
        await pool.getConnection();

      await connection.beginTransaction();

      transactionStarted = true;

      const [
        userRows
      ] = await connection.query(
        `
          SELECT
            id,
            full_name,
            username,
            email,
            role,
            status

          FROM admin_users

          WHERE id = ?

          LIMIT 1
          FOR UPDATE
        `,
        [
          adminUserId
        ]
      );

      const targetUser =
        userRows[0];

      if (!targetUser) {
        await connection.rollback();

        transactionStarted =
          false;

        return response.status(404).json({
          success: false,

          message:
            "The administrator account could not be found."
        });
      }

      const passwordHash =
        await bcrypt.hash(
          password,
          passwordSaltRounds
        );

      await connection.query(
        `
          UPDATE admin_users

          SET
            password_hash = ?,
            updated_at =
              CURRENT_TIMESTAMP

          WHERE id = ?
        `,
        [
          passwordHash,
          adminUserId
        ]
      );

      /*
       * Sign out the account everywhere
       * after the password changes.
       */
      await connection.query(
        `
          DELETE FROM admin_sessions
          WHERE admin_user_id = ?
        `,
        [
          adminUserId
        ]
      );

      await writeAdminAuditLog({
        connection,

        adminUserId:
          request.admin.id,

        action:
          "ADMIN_USER_PASSWORD_RESET",

        entityType:
          "admin_user",

        entityId:
          adminUserId,

        description:
          `Password reset for administrator ${targetUser.full_name}.`,

        metadata: {
          username:
            targetUser.username,

          email:
            targetUser.email,

          sessions_revoked:
            true
        },

        ipAddress:
          getRequestIp(
            request
          ),

        userAgent:
          getUserAgent(
            request
          )
      });

      await connection.commit();

      transactionStarted =
        false;

      return response.status(200).json({
        success: true,

        message:
          "Administrator password reset successfully. Existing sessions have been revoked.",

        data: {
          admin_user_id:
            adminUserId,

          sessions_revoked:
            true,

          requires_reauthentication:
            Number(
              request.admin.id
            ) ===
            Number(
              adminUserId
            )
        }
      });
    } catch (error) {
      if (
        connection &&
        transactionStarted
      ) {
        try {
          await connection.rollback();
        } catch (
          rollbackError
        ) {
          console.error(
            "Password reset rollback error:",
            rollbackError
          );
        }
      }

      console.error(
        "Reset administrator password error:",
        error
      );

      return sendDevelopmentError(
        response,
        error,
        "Unable to reset the administrator password."
      );
    } finally {
      if (connection) {
        connection.release();
      }
    }
  };

/* =========================================================
   REVOKE ADMINISTRATOR SESSIONS
   POST /api/admin/users/:adminUserId/revoke-sessions
   ========================================================= */

const revokeAdminUserSessions =
  async (
    request,
    response
  ) => {
    let connection = null;

    let transactionStarted =
      false;

    try {
      const adminUserId =
        normalizePositiveInteger(
          request.params
            .adminUserId
        );

      if (!adminUserId) {
        return response.status(422).json({
          success: false,

          message:
            "A valid administrator account is required."
        });
      }

      connection =
        await pool.getConnection();

      await connection.beginTransaction();

      transactionStarted = true;

      const [
        userRows
      ] = await connection.query(
        `
          SELECT
            id,
            full_name,
            username,
            email

          FROM admin_users

          WHERE id = ?

          LIMIT 1
          FOR UPDATE
        `,
        [
          adminUserId
        ]
      );

      const targetUser =
        userRows[0];

      if (!targetUser) {
        await connection.rollback();

        transactionStarted =
          false;

        return response.status(404).json({
          success: false,

          message:
            "The administrator account could not be found."
        });
      }

      const [
        deleteResult
      ] = await connection.query(
        `
          DELETE FROM admin_sessions
          WHERE admin_user_id = ?
        `,
        [
          adminUserId
        ]
      );

      await writeAdminAuditLog({
        connection,

        adminUserId:
          request.admin.id,

        action:
          "ADMIN_USER_SESSIONS_REVOKED",

        entityType:
          "admin_user",

        entityId:
          adminUserId,

        description:
          `All sessions revoked for administrator ${targetUser.full_name}.`,

        metadata: {
          username:
            targetUser.username,

          removed_sessions:
            deleteResult
              .affectedRows
        },

        ipAddress:
          getRequestIp(
            request
          ),

        userAgent:
          getUserAgent(
            request
          )
      });

      await connection.commit();

      transactionStarted =
        false;

      return response.status(200).json({
        success: true,

        message:
          "Administrator sessions revoked successfully.",

        data: {
          admin_user_id:
            adminUserId,

          revoked_sessions:
            toNumber(
              deleteResult
                .affectedRows
            )
        }
      });
    } catch (error) {
      if (
        connection &&
        transactionStarted
      ) {
        try {
          await connection.rollback();
        } catch (
          rollbackError
        ) {
          console.error(
            "Revoke sessions rollback error:",
            rollbackError
          );
        }
      }

      console.error(
        "Revoke administrator sessions error:",
        error
      );

      return sendDevelopmentError(
        response,
        error,
        "Unable to revoke administrator sessions."
      );
    } finally {
      if (connection) {
        connection.release();
      }
    }
  };

module.exports = {
  getAdminUsers,
  createAdminUser,
  updateAdminUser,
  updateAdminUserStatus,
  resetAdminUserPassword
};