import { Cookies } from 'react-cookie';
import { decodeToken, isValid, refreshAuth } from 'beta/utils/auth';
import { action, computed, extendObservable, makeObservable, observable } from 'mobx';
import { SalesChannel } from 'typings/graphql';

export interface IAccount {
  ssn: string;
  subscriptionId: string;
}

export type SelectedLocationState = {
  salesLocation: string;
  salesChannel: string;
};

export default class Authentication {
  constructor({ authentication = {} }, account: IAccount, c: string | object | null) {
    this.accountInput = account;
    this.cookies = new Cookies(c);

    makeObservable(this, {
      isLoggingOut: observable,
      staffSalesLocation: observable,
      isRefreshingAuth: observable,
      accountInput: observable,
      isTokenValid: computed,
      isStaff: computed,
      staffInStore: computed,
      setAccountInput: action,
      refresh: action,
      logout: action,
    });

    extendObservable(this, authentication);
  }

  cookies;

  isLoggingOut = false;

  isRefreshingAuth = false;

  staffSalesLocation: SelectedLocationState | undefined = undefined;

  accountInput: IAccount;

  get token(): string {
    return this.cookies.get('token');
  }

  get isTokenValid() {
    return this.token && isValid(this.token);
  }

  get isStaff() {
    return decodeToken(this.token)?.is_staff === 'true';
  }

  get username() {
    return decodeToken(this.token)?.name;
  }

  get email() {
    return decodeToken(this.token)?.email;
  }

  get loggedInUserSsn() {
    return decodeToken(this.token)?.ssn;
  }

  get customerId() {
    return decodeToken(this.token)?.customer_id;
  }

  get isEmailLogin() {
    return decodeToken(this.token)?.amr.includes('email');
  }

  get hasSalesLocation() {
    return this.staffSalesLocation?.salesChannel && this.staffSalesLocation.salesLocation;
  }

  get staffInStore() {
    return this.staffSalesLocation?.salesChannel === SalesChannel.Retail;
  }

  get isAudkenni() {
    return decodeToken(this.token)?.idp === 'audkenni';
  }

  getSalesLocations() {
    const salesLocation = this.cookies.get('salesLocation');
    const salesChannel = this.cookies.get('salesChannel');

    this.setSalesLocation({ salesChannel, salesLocation });
  }

  setSalesLocation = (selectedLocationState: SelectedLocationState) => {
    this.staffSalesLocation = selectedLocationState;

    if (selectedLocationState.salesLocation && selectedLocationState.salesChannel) {
      const expires = new Date(new Date().setFullYear(new Date().getFullYear() + 2));
      this.cookies.set('salesLocation', selectedLocationState.salesLocation, {
        path: '/',
        secure: true,
        expires,
      });

      this.cookies.set('salesChannel', selectedLocationState.salesChannel, {
        path: '/',
        secure: true,
        expires,
      });
    }
  };

  setAccountInput(
    ssn: string = this.accountInput?.ssn ?? '',
    subscriptionId: string = this.accountInput?.subscriptionId ?? '',
  ) {
    this.accountInput = { ssn, subscriptionId };
  }

  refresh = (returnPath?: string) => {
    this.isRefreshingAuth = true;

    if (returnPath) {
      refreshAuth(this.token, returnPath);
    } else {
      refreshAuth(this.token);
    }
  };

  logout = () => {
    this.isLoggingOut = true;
    this.cookies.remove('token', { path: '/' });
  };
}
