import GraphQLService from './GraphQLService';

interface GraphSignInData {
    username: string;
    identify: string;
  }
  
  interface GraphSignOPData {
    GraphSignin?: {
      jwt_access_token: string;
      jwt_refresh_token: string;
      username: string;
      email: string;
    };
  }
  
  interface GraphRefTokenOPData {
    GraphRefreshJWT?: {
      jwt_access_token: string;
      jwt_refresh_token: string;
      username: string;
      email: string;
    };
  }

  interface AppSignInBase {
    ar_id: number;
    keep_logged: string;
    un_pe_pm: string;
    device_token: string;
  }

  interface AppSignInData extends AppSignInBase {
    identify: string; 
  }
  
  interface AppSignInData2 extends AppSignInBase {
    otp: string; 
  }

  type AppSignInDataUnion = AppSignInData | AppSignInData2;


export interface Jwt {
    token: string;
    expiry: number;
  }

export interface AppSignOPData {
    AppSignin?:{
      id : number
      username : string
      primary_email : string
      primary_mobile : string
      primary_mobile_cc : string,
      authenticated?: {
        session? : {
          keep_logged : string
          id : number
          jwt : Jwt
        }
        uauthorisation?:{
          ar_id : number
        }
      }
    };
  }

  interface UserOPData {
    AppSignup?:{
      id: number;
      username: string;
      primary_email: string;
      primary_mobile: string;
      primary_mobile_cc: string;
      recovery_email: string;
      recovery_mobile: string;
      recovery_mobile_cc: string;
      signup_source: string;
      has_two_factor_auth: boolean;
      pemail_verified: boolean;
      pmobile_verified: boolean;
      created: string;
      updated: string;
    }
  }
  
  interface UserIPData {
    id?: number;
    username: string;
    primary_email: string;
    primary_mobile: string;
    primary_mobile_cc: string;
    signup_source: string;
  }

  interface AppSignoutResponse {
    AppSignout: boolean; 
  }
  
  interface ForgotPasswordInData {
    un_pe_pm: string;
    pass_recover_url: string;
  }

   interface ForgotPasswordOpData {
    AppForgotPassword?:{
      snapshot?: {
        message: string
      };
      pass_recover_token: string
    }
  }

  interface RecoverForgotPasswordInData {
    identify: string;
    identify_confirm: string;
    pass_recover_token: string;
    un_pe_pm: string;
  }

   interface RecoverForgotPasswordOpData {
    AppRecoverForgotPassword?:{
      snapshot?: {
        message: string
      };
      affected: number
    }
  }


class AuthenticationService extends GraphQLService {
    constructor() {
      super();
    }
  
  CheckUserAuthenticationMutation(GraphSignInData: GraphSignInData): Promise<GraphSignOPData | null |undefined> {
    const Query = `
      mutation GraphSignin($input: GraphLoginInput!) {
        GraphSignin(input: $input) {
          username
          email
          jwt_access_token
          jwt_refresh_token
        }
      }`;

    const variables = {
        input: GraphSignInData,
    };
    return this.mutate<GraphSignOPData>(Query, variables); 
  }

  getJWTUsingRefToken(jwtRefreshToken: string): Promise<GraphRefTokenOPData | null |undefined> {
    const Query = `
      mutation GraphRefreshJWT($jwtRefreshToken: String!) {
        GraphRefreshJWT(jwtRefreshToken: $jwtRefreshToken) {
          jwt_access_token
          jwt_refresh_token
          username
          email
        }
      }`;

    const variables = {
        "jwtRefreshToken": jwtRefreshToken,
    };
    return this.mutate<GraphRefTokenOPData>(Query, variables); 
  }

  AdminUserSigninMutation(AppSignInData: AppSignInDataUnion): Promise<AppSignOPData | null | undefined> {
    const Query = `mutation AppSignin($input: AppSigninInput!) {
        AppSignin(input: $input) {
            id
            username
            primary_email
            primary_mobile
            primary_mobile_cc
            authenticated {
              session {
                keep_logged
                jwt
                id
              }
              uauthorisation {
                ar_id
              }
            }
          }
       }`;

    const variables = {
      input: AppSignInData
    };
    return this.mutate<AppSignOPData>(Query, variables); 
  }

  AdminAppForgotPasswordMutation(ForgotPasswordInData: ForgotPasswordInData): Promise<ForgotPasswordOpData | null | undefined> {
    const Query = `mutation AppForgotPassword($input: AppForgotPasswordInput!) {
                    AppForgotPassword(input: $input) {
                      snapshot {
                        message
                      }
                      pass_recover_token
                    }
                  }`;

    const variables = {
      input: ForgotPasswordInData
    };
    return this.mutate<ForgotPasswordOpData>(Query, variables); 
  }

  AdminAppRecoverForgotPassword(RecoverForgotPasswordInData: RecoverForgotPasswordInData): Promise<RecoverForgotPasswordOpData | null | undefined> {
    const Query = `mutation AppRecoverForgotPassword($input: AppRecoverForgotPasswordInput!) {
                    AppRecoverForgotPassword(input: $input) {
                      snapshot {
                        message
                      }
                      affected
                    }
                  }`;

    const variables = {
      input: RecoverForgotPasswordInData
    };
    return this.mutate<RecoverForgotPasswordOpData>(Query, variables); 
  }

  AppSignUp(UserData: UserIPData): Promise<UserOPData |null | undefined> {
    const Query = `mutation AppSignup($input: AppSignupInput!) {
      AppSignup(input: $input) {
        id
        username
        primary_email
        primary_mobile
        primary_mobile_cc
        recovery_email
        recovery_mobile
        recovery_mobile_cc
        signup_source
        has_two_factor_auth
        pemail_verified
        pmobile_verified
        created
        updated
      }
    }`;

    const variables = {
      input: UserData
    };
    return this.mutate(Query, variables); 
  }

  AppSignout():Promise<AppSignoutResponse |null | undefined>{
    const GET_REFRESH_TOKEN =`
        mutation Mutation {
          AppSignout
        }`;

    return this.mutate(GET_REFRESH_TOKEN); 
  }

}

const authServiceInstance = new AuthenticationService();
export default authServiceInstance;