var admin = require("firebase-admin");
const logger = require("../utils/logger");
const path = require("path");
const { auth } = require("firebase-admin");
require("dotenv").config({
  path: path.resolve(
    process.cwd(),
    `.env.${process.env.NODE_ENV || "development"}`
  ),
});
const client = require("../graphql-client/graphql-client").client;
var serviceAccount = require(process.env.FIREBASE_ADMINSDK_JSON);

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

exports.admin = admin;

const adminEmail = [
  "patrick@imex.dev",
  //"patrick@imex.test",
  "patrick@imex.prod",
  "patrick@imexsystems.ca",
  "patrick@thinkimex.com",
];

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

  const { email, displayName, password, shopid, authlevel } = 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,
          authid: userRecord.uid,
          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);
  }
};

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

  if (!adminEmail.includes(req.user.email) && !req.user.ioadmin) {
    logger.log(
      "admin-update-user-unauthorized",
      "ERROR",
      req.user.email,
      null,
      {
        request: req.body,
        user: req.user,
      }
    );
    res.sendStatus(404);
    return;
  }

  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", "ADMIN", 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);
    });
};

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

  if (!adminEmail.includes(req.user.email) && !req.user.ioadmin) {
    logger.log(
      "admin-update-user-unauthorized",
      "ERROR",
      req.user.email,
      null,
      {
        request: req.body,
        user: req.user,
      }
    );
    res.sendStatus(404);
    return;
  }

  admin
    .auth()
    .getUser(req.body.uid)
    .then((userRecord) => {
      res.json(userRecord);
    })
    .catch((error) => {
      logger.log("admin-get-user-error", "ERROR", req.user.email, null, {
        error,
      });
      res.status(500).json(error);
    });
};

exports.sendNotification = async (req, res) => {
  setTimeout(() => {
    // Send a message to the device corresponding to the provided
    // registration token.
    admin
      .messaging()
      .send({
        topic: "PRD_PATRICK-messaging",
        notification: {
          title: `ImEX Online Message - +16049992002`,
          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.
        console.log("Successfully sent message:", response);
      })
      .catch((error) => {
        console.log("Error sending message:", error);
      });

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

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

  res.json(result);
};

exports.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) {
    res.sendStatus(500);
  }
};

exports.validateFirebaseIdToken = async (req, res, next) => {
  if (
    (!req.headers.authorization ||
      !req.headers.authorization.startsWith("Bearer ")) &&
    !(req.cookies && req.cookies.__session)
  ) {
    console.error("Unauthorized attempt. No authorization provided.");
    res.status(403).send("Unauthorized");
    return;
  }

  let idToken;
  if (
    req.headers.authorization &&
    req.headers.authorization.startsWith("Bearer ")
  ) {
    // console.log('Found "Authorization" header');
    // Read the ID Token from the Authorization header.
    idToken = req.headers.authorization.split("Bearer ")[1];
  } else if (req.cookies) {
    //console.log('Found "__session" cookie');
    // Read the ID Token from cookie.
    idToken = req.cookies.__session;
  } else {
    // No cookie
    console.error("Unauthorized attempt. No cookie provided.");
    logger.log("api-unauthorized-call", "WARN", null, null, {
      req,
      type: "no-cookie",
    });
    res.status(403).send("Unauthorized");
    return;
  }

  try {
    const decodedIdToken = await admin.auth().verifyIdToken(idToken);
    //console.log("ID Token correctly decoded", decodedIdToken);
    req.user = decodedIdToken;
    next();
    return;
  } catch (error) {
    logger.log("api-unauthorized-call", "WARN", null, null, {
      path: req.path,
      body: req.body,

      type: "unauthroized",
      ...error,
    });

    res.status(401).send("Unauthorized");
    return;
  }
};

exports.validateAdmin = async (req, res, next) => {
  if (!adminEmail.includes(req.user.email) && !req.user.ioadmin) {
    logger.log("admin-validation-failed", "ERROR", req.user.email, null, {
      request: req.body,
      user: req.user,
    });
    res.sendStatus(404);
    return;
  } else {
    next();
    return;
  }
};

//Admin claims code.
// const uid = "JEqqYlsadwPEXIiyRBR55fflfko1";

// admin
//   .auth()
//   .getUser(uid)
//   .then((user) => {
//     console.log(user);
//     admin.auth().setCustomUserClaims(uid, {
//       ioadmin: true,
//       "https://hasura.io/jwt/claims": {
//         "x-hasura-default-role": "admin",
//         "x-hasura-allowed-roles": ["admin"],
//         "x-hasura-user-id": uid,
//       },
//     });
//   });
