export const apple_login = [
    {
        id: "appleLoginMobileEndpoint",
        name: "Apple Login Mobile Endpoint",
        description: "Endpoint for login via iOS app",
        method: "POST",
        route: "/v3/api/custom/lambda/apple/login/mobile",
        inputs: [
          {
            name: "first_name",
            type: "body",
            rules: "",
            dataType: "String"
          },
          {
            name: "last_name",
            type: "body",
            rules: "",
            dataType: "String"
          },
          {
            name: "identityToken",
            type: "body",
            rules: "",
            dataType: "String"
          },
          {
            name: "apple_id",
            type: "body",
            rules: "",
            dataType: "String"
          },
          {
            name: "role",
            type: "body",
            rules: "",
            dataType: "String"
          }
        ],
        response: [
          {
            id: "error",
            key: "error",
            value: "false",
            valueType: "Boolean",
            parent: ""
          },
          {
            id: "role",
            key: "role",
            value: "",
            valueType: "String",
            parent: ""
          },
          {
            id: "access_token",
            key: "access_token",
            value: "",
            valueType: "String",
            parent: ""
          },
          {
            id: "refresh_token",
            key: "refresh_token",
            value: "",
            valueType: "String",
            parent: ""
          },
          {
            id: "expire_at",
            key: "expire_at",
            value: "",
            valueType: "String",
            parent: ""
          },
          {
            id: "user_id",
            key: "user_id",
            value: "",
            valueType: "String",
            parent: ""
          }
        ],
        code: `
        app.post("/v3/api/custom/lambda/apple/login/mobile", middlewares, async function (req, res) {
            //This endpoint is for login via IOS APP.
            const sdk = req.sdk;
            try {
              const { first_name, last_name, identityToken, apple_id, role } = req.body;
              const data = jwt.decode(identityToken, { complete: true });
              logService.log(data);
              const kid = data.header.kid;
        
              const appleSigningKey = await JwtService.getAppleSigningKeys(kid);
        
              const payload = await JwtService.verifyAppleLogin(identityToken, appleSigningKey);
        
              logService.log(payload);
        
              if (payload.sub != apple_id) {
                throw new Error("Invalid Identity");
              }
              const user_details = {
                first_name: first_name,
                last_name: last_name,
                email: payload.email,
                apple_id: apple_id
              };
              const service = new AuthService();
        
              const id = await service.appleLogin(sdk, req.projectId, user_details, identityToken, role);
        
              let new_jwt = JwtService.createAccessToken(
                {
                  user_id: id,
                  role: role
                },
                config.jwt_expire,
                config.jwt_key
              );
        
              let refreshToken = JwtService.createAccessToken(
                {
                  user_id: id,
                  role: role
                },
                config.refresh_jwt_expire,
                config.jwt_key
              );
              let expireDate = new Date();
              expireDate.setSeconds(expireDate.getSeconds() + config.refresh_jwt_expire);
              await service.saveRefreshToken(req.sdk, req.projectId, id, refreshToken, expireDate);
        
              return res.status(200).json({
                error: false,
                role: role,
                access_token: new_jwt,
                refresh_token: refreshToken,
                expire_at: config.jwt_expire,
                user_id: id
              });
            } catch (error) {
              console.log(error);
              return res.status(403).json({
                error: true,
                message: error.message
              });
            }
          });
        
        `,
        doc: "",
        unit: "",
        protected: false,
        authorizedRoles: [],
        imports: "",
        type: "default",
        group: "apple_login"
      },
      {
        id: "appleLogin",
        name: "Apple Login",
        description: "Endpoint for Apple login",
        method: "GET",
        route: "/v3/api/custom/lambda/apple/login",
        inputs: [],
        response: [
          {
            id: "error",
            key: "error",
            value: "true",
            valueType: "Boolean",
            parent: ""
          },
          {
            id: "message",
            key: "message",
            value: "",
            valueType: "String",
            parent: ""
          }
        ],
        code: `

        app.get("/v3/api/custom/lambda/apple/login", middlewares, async function (req, res) {
            try {
              if (req.query.role === "admin") return res.status(403).json({ error: true, message: "Can't register admin with this API" });
              
              let companyState = '';
              if(req.query.company_id != undefined){
                companyState += "~"  + req.query.company_id
              }
        
              const options = {
                clientID: config.apple.client_id, // Apple Client ID
                redirectUri: config.apple.redirect_url,
                state: req.headers["x-project"] + "~" + req.query.role + companyState,
                responseMode: "query" | "fragment" | "form_post",
                scope: "email"
              };
        
              const authorizationUrl = appleSignin.getAuthorizationUrl(options);
        
              logService.log(authorizationUrl);
        
              return res.send(authorizationUrl);
            } catch (err) {
              return res.status(403).json({
                error: true,
                message: err.message
              });
            }
          });
        
        
        `,
        doc: "",
        unit: "",
        protected: false,
        authorizedRoles: [],
        imports: "",
        type: "default",
        group: "apple_login"
      },
      {
        id: "appleAuthCode",
        name: "Apple Auth Code ",
        description: "Endpoint for handling Apple authorization code",
        method: "POST",
        route: "/v3/api/custom/lambda/apple/code",
        inputs: [],
        response: [
          {
            id: "error",
            key: "error",
            value: "true",
            valueType: "Boolean",
            parent: ""
          },
          {
            id: "message",
            key: "message",
            value: "",
            valueType: "String",
            parent: ""
          }
        ],
        code: `
        
        app.post("/v3/api/custom/lambda/apple/code", async function (req, res) {
            try {
              const { code, state } = req.body;
        
              console.log(code, state);
        
              const parts = state.split("~");
              const base64DecodeBuffer = new Buffer.from(parts[0], "base64");
              let base64Decode = base64DecodeBuffer.toString("ascii").split(":");
              const projectId = base64Decode[0];
              const role = parts[1];
              const database = base64Decode[2]?? config.databaseName;
        
              let sdk = new BackendSDK();
              sdk.setDatabase(database);
              sdk.setProjectId(projectId);
        
              const clientSecret = appleSignin.getClientSecret({
                clientID: config.apple.client_id, // Apple Client ID
                teamID: config.apple.team_id, // Apple Developer Team ID.
                privateKey: config.apple.private_key, // private key associated with your client ID. -- Or provide a \`privateKeyPath\` property instead.
                keyIdentifier: config.apple.key_id // identifier of the private key.
              });
        
              const options = {
                clientID: config.apple.client_id, // Apple Client ID
                redirectUri: config.apple.redirect_url, // use the same value which you passed to authorisation URL.
                clientSecret: clientSecret
              };
        
              const tokenResponse = await appleSignin.getAuthorizationToken(code, options);
        
              const identityToken = tokenResponse.id_token;
        
              const data = jwt.decode(identityToken, { complete: true });
        
              if (!data) {
                throw new Error("Invalid_grant");
              }
        
              const kid = data.header.kid;
        
              const appleSigningKey = await JwtService.getAppleSigningKeys(kid);
        
              const payload = await JwtService.verifyAppleLogin(identityToken, appleSigningKey);
        
              const user_details = {
                first_name: " ",
                last_name: " ",
                email: payload.sub
              };
              const service = new AuthService();
              if (!user_details.email) {
                throw new Error("Could not access email address");
              }
        
              let apple_login_res;
              if (parts[2]) {
                const company_id = parts[2];
                sdk.setProjectId(projectId);
                sdk.setTable("company");
                const company = await sdk.get({ id: company_id });
                if (!company) {
                  return res.status(404).json({ message: "Company Not found", error: true });
                }
                apple_login_res = await service.appleLogin(sdk, projectId, user_details, identityToken, role, company_id);
              } else {
                apple_login_res = await service.appleLogin(sdk, projectId, user_details, identityToken, role);
              }
        
              const { id, is_newuser } = apple_login_res;
              let new_jwt = JwtService.createAccessToken(
                {
                  user_id: id,
                  role: role
                },
                config.jwt_expire,
                config.jwt_key
              );
        
              let refreshToken = JwtService.createAccessToken(
                {
                  user_id: id,
                  role: role
                },
                config.refresh_jwt_expire,
                config.jwt_key
              );
              let expireDate = new Date();
              expireDate.setSeconds(expireDate.getSeconds() + config.refresh_jwt_expire);
              await service.saveRefreshToken(sdk, req.projectId, id, refreshToken, expireDate);
        
              // Remark: Fetching Project
           
              let project = {};
        
              if (config.env == "production") {
                project = require("../project");
                
              } else {
                sdk.setProjectId("manaknight");
                sdk.setTable("projects");
          
                project = (await sdk.get({
                  project_id: projectId
                }))[0];
        
              }
        
              const resData = JSON.stringify({
                error: false,
                role: role,
                access_token: new_jwt,
                refresh_token: refreshToken,
                expire_at: config.jwt_expire,
                user_id: id,
                state: state,
                is_newuser: is_newuser
              });
        
              const encodedURI = encodeURI(resData);
        
              res.redirect(\`https://\${project.hostname}/login/oauth?data=\${encodedURI}\`);
            } catch (err) {
              console.log(err);
              return res.status(403).json({
                error: true,
                message: err.message
              });
            }
          });
        
        
        `,
        doc: "",
        unit: "",
        protected: false,
        authorizedRoles: [],
        imports: "",
        type: "default",
        group: "apple_login"
      }
      
]


export const appleLoginImports = `

    const AuthService = require("../../../services/AuthService");
    const JwtService = require("../../../services/JwtService");
    const ProjectMiddleware = require("../../../middleware/ProjectMiddleware");
    const PermissionMiddleware = require("../../../middleware/PermissionMiddleware");
    const UrlMiddleware = require("../../../middleware/UrlMiddleware");
    const HostMiddleware = require("../../../middleware/HostMiddleware");
    const DevLogService = require("../../../services/DevLogService");
    const jwt = require("jsonwebtoken");
    const appleSignin = require("apple-signin-auth");
    const BackendSDK = require('../../../core/BackendSDK');

    const middlewares = [
    ProjectMiddleware,
    UrlMiddleware,
    HostMiddleware,
    PermissionMiddleware
    // RateLimitMiddleware,
    // LogMiddleware,
    // UsageMiddleware
    // CheckProjectMiddleware,
    // AnalyticMiddleware,
    // RoleMiddleware
    ];

    let logService = new DevLogService();

    const config = require("../../../config");

`