import { MainStateManager } from './MainStateManager';
import { Login } from './Login/Login';
import { TabPageData } from './Page/Tab/TabData';
import { IData } from './Data';
import { IReportInfoing } from './ReportInfo';

interface IUser {
  id: number;
  accessToken: string;
  userName: string;
  firstName: string;
  lastName: string;
  picture: string;
  smallPicture: string;
  reportInfo: IReportInfoing[];
  attachedData: IData[];
  roles: string[];
  userOptions: IUserOption[];
  userColumns: IUserColumn[];
}

interface IUserOption {
  key: string;
  form: any;
  value: any;
}
export class UserOption {
  public value: any;
  constructor(
    public key: string,
    public form: any,
    value: any
  ) {
    this.value = value.toString();
  }

  static deserialize(userOption: IUserOption) {
    return new UserOption(userOption.key, userOption.form, userOption.value);
  }
}


interface IUserColumn {
  key: string;
  form: any;
  width: any;
}
export class UserColumn {
  constructor(
    public key: string,
    public form: any,
    public width: number,
  ) {
  }

  static deserialize(userColumn: IUserColumn) {
    return new UserColumn(userColumn.key, userColumn.form, userColumn.width);
  }
}


type IUserLoginFormState = | 'login' | 'signup' | 'verify' | 'error' | 'MobileRegistered';
export class User {
  public isInRole = <T extends { selfRole: string; }>(main: T, role: keyof T): boolean => {
    if (this.isThisUserAdmin) {
      return true;
    } else if (this.roles.includes(main.selfRole)) {
      return true;
    } else if (this.roles.includes((main.selfRole + '_' + main[role]).toLowerCase())) {
      return true;
    }
    return false;
  }
  private _isThisUserAdmin = (): void => {
    if (this.roles.find(i => i === 'Admin'.toLowerCase())) {
      this.isThisUserAdmin = true;
    } else {
      this.isThisUserAdmin = false;
    }
  }

  public userLoginFormState: IUserLoginFormState = 'login';

  public headers = () => {
    if (this.accessToken) {
      return {
        Authorization: `bearer ${this.accessToken}`,
      };
    } else {
      return undefined;
    }
  }

  public id: number = 0;
  public accessToken: string = '';
  public userName: string = '';
  public firstName: string = '';
  public lastName: string = '';
  public picture: string = '';
  public smallPicture: string = '';
  public rememberMe: boolean = false;
  public roles: string[] = [];
  public userOptions: UserOption[] = [];
  public userColumns: UserColumn[] = [];
  public isThisUserAdmin: boolean = false;


  public LoginFactory = Login.buildNew(this.mainStateManager);

  public intervalForBackgroundChangePage?: NodeJS.Timeout;
  public initializingUserBackground: boolean = false;
  public userBackgrounDiv?: HTMLElement;

  constructor(public mainStateManager: MainStateManager) { }

  unMountUserPage() {
    this.initializingUserBackground = false;
    this.userBackgrounDiv = undefined;
    if (this.intervalForBackgroundChangePage) {
      clearInterval(this.intervalForBackgroundChangePage);
    }
  }

  loginDataLoad = () => {
    const userPropertyString = localStorage.getItem('userProperty');
    if (userPropertyString) {
      this.rememberMe = true;
      const userProperty = new UserProperty(JSON.parse(userPropertyString));
      if (userProperty && userProperty.accessToken) {
        this.accessToken = userProperty.accessToken;

        this.LoginFactory = Login.buildNew(this.mainStateManager);

        // this.LoginFactory.get('user', 'TokenValidation', (response: AxiosResponse) =>
        //   this.validateToken(response, userProperty, this.rememberMe),
        //   this.unauthorized
        // );

        // this.LoginFactory.get<any, any>('user', 'tokenValidation')
        //   .then(response => {
        //     if (response.isSuccess) {
        //       // this.mainStateManager.Usering.LoginFactory.loadingState = 'none';
        //       const userData: IUser = response.data;
        //       userProperty.firstName = userData.firstName;
        //       userProperty.lastName = userData.lastName;
        //       userProperty.userName = userData.userName;
        //       userProperty.id = userData.id;
        //       userProperty.picture = userData.picture;
        //       userProperty.smallPicture = userData.smallPicture;
        //       userProperty.roles = userData.roles;
        //       this.userLogin(userData, this.rememberMe);
        //     } else {
        //       localStorage.removeItem('userProperty');
        //       this.gotoLoginPage();
        //     }
        //   })
        //   .catch(error => {
        //     localStorage.removeItem('userProperty');
        //     this.gotoLoginPage();
        //   })

        return;
      }
    }
    this.gotoLoginPage();
  };

  // validateToken = (response: AxiosResponse, userProperty: UserProperty, rememberMe: boolean) => {
  //   if (response.status === 200 && response.data.isSuccess) {
  //     const userData: IUser = response.data.data;
  //     userProperty.firstName = userData.firstName;
  //     userProperty.lastName = userData.lastName;
  //     userProperty.userName = userData.userName;
  //     userProperty.id = userData.id;
  //     userProperty.picture = userData.picture;
  //     userProperty.smallPicture = userData.smallPicture;
  //     userProperty.roles = userData.roles;
  //     this.userLogin(userData, rememberMe);
  //   } else {
  //     localStorage.removeItem('userProperty');
  //     this.gotoLoginPage();
  //   }
  // };

  // unauthorized = (error: AxiosError) => {
  //   localStorage.removeItem('userProperty');
  //   this.gotoLoginPage();
  // };

  logOut = () => {
    localStorage.removeItem('userProperty');
    this.gotoLoginPage();
  };

  gotoLoginPage = () => {
    // this.mainStateManager.Usering.LoginFactory.loadingState = 'none';
    this.LoginFactory.pageData = new TabPageData(this.mainStateManager);
    // this.mainStateManager.Eventing.trigger('userLoginLoadData');
  };

  userLogin = (response: IUser, rememberMe: boolean) => {
    this.id = response.id;
    this.userName = response.userName;
    this.accessToken = response.accessToken;
    this.firstName = response.firstName;
    this.lastName = response.lastName;
    this.smallPicture = response.smallPicture;
    this.roles = response.roles.map(i => i.toLowerCase());
    // this.mainStateManager.ReportInfoing.userLogin(response.reportInfo);
    this._isThisUserAdmin();
    this.userOptions = response.userOptions?.map(i => UserOption.deserialize(i));
    this.userColumns = response.userColumns?.map(i => UserColumn.deserialize(i));

    // this.mainStateManager.Dataing.deserialize(response.attachedData);

    this.rememberMe = rememberMe;
    if (rememberMe) {
      localStorage.setItem('userProperty', JSON.stringify({ accessToken: this.accessToken, }));
    }

    // this.mainStateManager.generateTheme();

    // this.mainStateManager.Eventing.trigger('userLoginSuccess');
  };

  userChangeData = (response: IUser) => {
    this.userName = response.userName;
    this.accessToken = response.accessToken;
    this.firstName = response.firstName;
    this.lastName = response.lastName;
    this.smallPicture = response.smallPicture;
    this.roles = response.roles;
    this.userOptions = response.userOptions.map(i => UserOption.deserialize(i));

    if (this.rememberMe) {
      localStorage.setItem('userProperty', JSON.stringify({ accessToken: this.accessToken, }));
    }

    // this.mainStateManager.Dataing.deserialize(response.attachedData);
    // this.mainStateManager.Eventing.trigger('loadLanguagesSuccess');
  };

  getFormUserOptions = (keyOfForm: any): UserOption[] => {
    return this.userOptions.filter(i => i.form === keyOfForm);
  }
  // addUserOption = (key: string, pageKeys: string[], value: string, isSave?: boolean) => {
  //   pageKeys.forEach((i: any) => {
  //     const userOption = new UserOption(key, i, value);
  //     this.userOptions.push(userOption);

  //     if (isSave) {
  //       this.LoginFactory.post('User', 'AddUserOption', userOption);
  //     }
  //   });

  //   this.updateUserOptionTabPage(pageKeys);
  // }
  // removeUserOption = (key: string, pageKeys: string[], isSave?: boolean) => {
  //   this.userOptions = this.userOptions.filter(i => !(i.key === key && pageKeys.includes(i.form)));
  //   if (isSave) {
  //     pageKeys.forEach(i => {
  //       const result = { key: key, form: i };

  //       this.LoginFactory.post('User', 'DeleteUserOption', result);
  //     });
  //   }

  //   this.updateUserOptionTabPage(pageKeys);
  // }

  // saveUserOption = (key: string, pageKeys: string[], value: string) => {
  //   pageKeys.forEach((i: any) => {
  //     const result: IUserOption = { key: key, form: i, value: value };

  //     this.LoginFactory.post('User', 'AddUserOption', result);
  //   });
  // }


  // public setUserOption = <V>(key: string, pageKey: string, value: V, defaultValue: V, isSave?: boolean) => {

  //   const finded = this.userOptions.find(i => i.key === key && i.form === pageKey);

  //   const valueString = (value as any).toString();
  //   if (finded) {
  //     const defaultValueString = (defaultValue as any).toString();

  //     if (valueString === defaultValueString) {
  //       this.removeUserOption(finded.key, [finded.form], true);
  //     } else {
  //       finded.value = valueString;
  //       if (isSave) {
  //         this.saveUserOption(finded.key, [finded.form], valueString);
  //       }
  //     }
  //   } else {
  //     this.addUserOption(key, [pageKey], valueString, isSave);
  //   }
  // }

  private updateUserOptionTabPage(pageKeys: string[]) {
    // this.mainStateManager.Tabing.tabs.forEach((page: any) => {
    //   if (pageKeys.includes(page.pageKey)) {
    //     page.userOptions = this.userOptions?.filter(i => i.form === page.pageKey);
    //   }
    // });
  }
}

class UserProperty {
  public id: number;
  public userName: string;
  public firstName: string;
  public lastName: string;
  public accessToken: string;
  public picture: string;
  public smallPicture: string;
  public roles: string[];
  constructor(values: any) {
    this.id = values.id;
    this.userName = values.userName;
    this.firstName = values.firstName;
    this.lastName = values.lastName;
    this.accessToken = values.accessToken;
    this.picture = values.picture;
    this.smallPicture = values.smallPicture;
    this.roles = values.roles;
  }
}
