const serviceAccount = require(process.env.FIREBASE_ADMINSDK_JSON);
const admin = require("firebase-admin");
const moment = require("moment-timezone");
const logger = require("../utils/logger");
const client = require("../graphql-client/graphql-client").client;
const { sendWelcomeEmail } = require("../email/sendemail");
const { GET_USER_BY_EMAIL } = require("../graphql-client/queries");

admin.initializeApp({
  credential: admin.credential.cert(serviceAccount),
  databaseURL: process.env.FIREBASE_DATABASE_URL
});

const createUser = async (req, res) => {
  logger.log("admin-create-user", "debug", req.user.email, null, {
    request: req.body,
    ioadmin: true
  });

  const { email, displayName, password, shopid, authlevel, validemail } = req.body;

  try {
    const userRecord = await admin.auth().createUser({ email, displayName, password });

    // See the UserRecord reference doc for the contents of userRecord.

    const result = await client.request(
      `
        mutation INSERT_USER($user: users_insert_input!) {
          insert_users_one(object: $user) {
            email
          }
        }
      `,
      {
        user: {
          email: email.toLowerCase(),
          authid: userRecord.uid,
          validemail,
          associations: {
            data: [{ shopid, authlevel, active: true }]
          }
        }
      }
    );

    res.json({ userRecord, result });
  } catch (error) {
    logger.log("admin-update-user-error", "ERROR", req.user.email, null, {
      error
    });
    res.status(500).json(error);
  }
};

const updateUser = (req, res) => {
  logger.log("admin-update-user", "debug", req.user.email, null, {
    request: req.body,
    ioadmin: true
  });

  admin
    .auth()
    .updateUser(
      req.body.uid,
      req.body.user
      // {
      // email: "modifiedUser@example.com",
      // phoneNumber: "+11234567890",
      // emailVerified: true,
      // password: "newPassword",
      // displayName: "Jane Doe",
      // photoURL: "http://www.example.com/12345678/photo.png",
      // disabled: true,
      // }
    )
    .then((userRecord) => {
      // See the UserRecord reference doc for the contents of userRecord.

      logger.log("admin-update-user-success", "debug", req.user.email, null, {
        userRecord,
        ioadmin: true
      });
      res.json(userRecord);
    })
    .catch((error) => {
      logger.log("admin-update-user-error", "ERROR", req.user.email, null, {
        error
      });
      res.status(500).json(error);
    });
};

const getUser = (req, res) => {
  logger.log("admin-get-user", "debug", req.user.email, null, {
    request: req.body,
    ioadmin: true
  });

  admin
    .auth()
    .getUser(req.body.uid)
    .then((userRecord) => {
      return client
        .request(
          `
          query GET_USER_BY_AUTHID($authid: String!) {
            users(where: { authid: { _eq: $authid } }) {
              email
              validemail
              associations {
                id
                shopid
                bodyshop {
                  id
                  convenient_company
                }
              }
            }
          }
          `,
          { authid: req.body.uid }
        )
        .then((dbUserResult) => {
          res.json({
            ...userRecord,
            db: {
              validemail: dbUserResult?.users?.[0]?.validemail,
              company: dbUserResult?.users?.[0]?.associations?.[0]?.bodyshop?.convenient_company
            }
          });
        });
    })
    .catch((error) => {
      logger.log("admin-get-user-error", "ERROR", req.user.email, null, {
        error
      });
      res.status(500).json(error);
    });
};

const sendNotification = async (req, res) => {
  setTimeout(() => {
    // Send a message to the device corresponding to the provided
    // registration token.
    admin
      .messaging()
      .send({
        topic: req.body.topic,
        notification: {
          title: `ImEX Online Message - `,
          body: "Test Noti."
          //imageUrl: "https://thinkimex.com/img/io-fcm.png",
        },
        data: {
          type: "messaging-inbound",
          conversationid: "e0eb17c3-3a78-4e3f-b932-55ef35aa2297",
          text: "Hello. ",
          image_path: "",
          phone_num: "+16049992002"
        }
      })
      .then((response) => {
        // Response is a message ID string.
        logger.log("Successfully sent message:", "debug", req?.user?.email, null, {
          response
        });
      })
      .catch((error) => {
        logger.log("Successfully sent message:", "error", req?.user?.email, null, {
          error
        });
      });

    res.sendStatus(200);
  }, 500);
};

const subscribe = async (req, res) => {
  const result = await admin
    .messaging()
    .subscribeToTopic(req.body.fcm_tokens, `${req.body.imexshopid}-${req.body.type}`);

  res.json(result);
};

const unsubscribe = async (req, res) => {
  try {
    const result = await admin
      .messaging()
      .unsubscribeFromTopic(req.body.fcm_tokens, `${req.body.imexshopid}-${req.body.type}`);

    res.json(result);
  } catch (error) {
    logger.log("admin-unsubscribe-error", "ERROR", req.user.email, null, { error: error.message });
    res.sendStatus(500);
  }
};

const getWelcomeEmail = async (req, res) => {
  const { authid, email, bcc } = req.body;

  try {
    // Fetch user from Firebase
    const userRecord = await admin.auth().getUser(authid);
    if (!userRecord) {
      throw { status: 404, message: "User not found in Firebase." };
    }

    // Fetch user data from the database using GraphQL
    const dbUserResult = await client.request(GET_USER_BY_EMAIL, { email: email.toLowerCase() });

    const dbUser = dbUserResult?.users?.[0];
    if (!dbUser) {
      throw { status: 404, message: "User not found in database." };
    }

    // Validate email before proceeding
    if (!dbUser.validemail) {
      logger.log("admin-send-welcome-email-skip", "debug", req.user.email, null, {
        message: "User email is not valid, skipping email.",
        email
      });
      return res.status(200).json({ message: "User email is not valid, email not sent." });
    }

    // Generate password reset link
    const resetLink = await admin.auth().generatePasswordResetLink(dbUser.email);

    // Send welcome email
    await sendWelcomeEmail({
      to: dbUser.email,
      resetLink,
      dateLine: moment().tz(dbUser.associations?.[0]?.bodyshop?.timezone).format("MM/DD/YYYY @ hh:mm a"),
      features: dbUser.associations?.[0]?.bodyshop?.features,
      bcc
    });

    // Log success and return response
    logger.log("admin-send-welcome-email", "debug", req.user.email, null, {
      request: req.body,
      ioadmin: true,
      emailSentTo: email
    });

    return res.status(200).json({ message: "Welcome email sent successfully." });
  } catch (error) {
    logger.log("admin-send-welcome-email-error", "ERROR", req.user.email, null, { error });

    if (!res.headersSent) {
      return res.status(error.status || 500).json({
        message: error.message || "Error sending welcome email.",
        error
      });
    }
  }
};

const getResetLink = async (req, res) => {
  const { authid, email } = req.body;
  logger.log("admin-reset-link", "debug", req.user.email, null, { authid, email });

  try {
    // Fetch user from Firebase
    const userRecord = await admin.auth().getUser(authid);
    if (!userRecord) {
      throw { status: 404, message: "User not found in Firebase." };
    }

    // Generate password reset link
    const resetLink = await admin.auth().generatePasswordResetLink(email);

    // Log success and return response
    logger.log("admin-reset-link-success", "debug", req.user.email, null, {
      request: req.body,
      ioadmin: true
    });

    return res.status(200).json({ message: "Reset link generated successfully.", resetLink });
  } catch (error) {
    return res.status(error.status || 500).json({
      message: error.message || "Error generating reset link.",
      error
    });
  }
};

module.exports = {
  admin,
  createUser,
  updateUser,
  getUser,
  sendNotification,
  subscribe,
  unsubscribe,
  getWelcomeEmail,
  getResetLink
};
