import { Component } from '@angular/core';
import { Router } from '@angular/router';
import { Store } from '@ngrx/store';
import { SignupStore } from 'src/app/core/interfaces/store/signup.store';
import { UserGender } from 'src/app/core/interfaces/user.interface';
import { SignupDispatchers } from 'src/app/core/stores/index.dispatchers';
import { UserService } from 'src/app/shared/services/user/user.service';

@Component({
  selector: 'app-person',
  templateUrl: './person.component.html',
  styleUrls: ['./person.component.scss'],
})
export class PersonComponent {
  user: SignupStore = {
    fullName: '',
    username: '',
    email: '',
    password: '',
    gender: 'male',
    weight: 0,
    height: 0,
    birthDate: new Date(),
    goalId: 0,
    physicalActivityId: 0,
  };

  dateIsValid = true;

  genderOptions: Record<string, UserGender> = {
    Masculino: 'male',
    Feminino: 'female',
  };
  genderOptionsLabels = Object.keys(this.genderOptions);

  dateRegex = new RegExp('^[0-9]{2}/[0-9]{2}/[0-9]{4}$');

  tmb = 0;

  constructor(
    private store: Store<{ signup: SignupStore }>,
    private router: Router,
    private userService: UserService,
    private signupDispatchers: SignupDispatchers,
  ) {}

  async ngOnInit() {
    try {
      Object.assign(this.user, await this.getUserUsingStore());
      !this.isSocialSignup() && this.verifyPreviousData();
    } catch (err) {
      this.router.navigate(['/app/auth/signup']);
    }
  }

  getUserUsingStore() {
    return new Promise(
      (
        resolve: (user: SignupStore) => void,
        reject: (error: unknown) => void,
      ) => {
        this.store.select('signup').subscribe({
          next: resolve,
          error: reject,
        });
      },
    );
  }

  isSocialSignup() {
    return this.user.googleToken;
  }

  verifyPreviousData() {
    type RequiredData = Pick<
      SignupStore,
      'fullName' | 'username' | 'email' | 'password'
    >;

    const dataToVerify: RequiredData = {
      fullName: this.user.fullName,
      username: this.user.username,
      email: this.user.email,
      password: this.user.password,
    };

    if (Object.values(dataToVerify).some((v) => !v)) {
      this.router.navigate(['/app/auth/signup']);
    }
  }

  handleGoBack() {
    this.router.navigate(['/app/auth/signup']);
  }

  handleGenderChange(label: string) {
    const genderSelected = this.genderOptions[label];
    this.user.gender = genderSelected;
  }

  getBirthDate() {
    const birthDate = this.user.birthDate;

    if (!birthDate) return '';
    return new Date(birthDate).toISOString().split('T')[0];
  }

  handleBirthDateChange(value: string) {
    if (!value) {
      this.dateIsValid = false;
      return;
    }

    const [year, month, day] = value.split('-');
    const birthDate = new Date(`${year}-${month}-${day}T00:00:00`);

    const age = this.userService.calculateAge(birthDate);

    if (!age || age > 100 || age < 0) {
      this.dateIsValid = false;
      return;
    }

    this.user.birthDate = birthDate;
    this.dateIsValid = true;
  }

  isFormValid() {
    const { gender, weight, height } = this.user;
    const age = this.userService.calculateAge(this.user.birthDate);

    if (!gender) return false;
    if (!weight || weight <= 1) return false;
    if (!height || height <= 0.1) return false;
    if (!this.dateIsValid || !age || age > 100) return false;

    return true;
  }

  calculateTmb(): number {
    const { gender, weight, height, birthDate } = this.user;
    const age = this.userService.calculateAge(birthDate);

    if (!this.isFormValid() || !age) {
      this.tmb = 0;
      return 0;
    }

    this.tmb = Math.round(
      this.userService.calculateTMB(gender, weight, height * 100, age),
    );
    return this.tmb;
  }

  continueSignup() {
    this.signupDispatchers.setSignup(this.user);
    this.router.navigate(['/app/auth/signup/activity']);
  }
}
