import { inject, Injectable } from '@angular/core';

import { TranslateService } from '@ngx-translate/core';
import { Action, Selector, State, StateContext, Store } from '@ngxs/store';
import { tap } from 'rxjs';

import { SetDefaultLanguageAction } from '../action/language.action';
import { GetSettingOptionAction, SelectedCurrencyAction } from '../action/setting.action';
import { ICurrency } from '../interface/currency.interface';
import { IValues } from '../interface/setting.interface';
import { SettingService } from '../services/setting.service';

export class SettingStateModel {
  setting: IValues | null;
  selectedCurrency: ICurrency | null;
}

@State<SettingStateModel>({
  name: 'setting',
  defaults: {
    setting: null,
    selectedCurrency: null,
  },
})
@Injectable()
export class SettingState {
  private settingService = inject(SettingService);
  private store = inject(Store);
  private translate = inject(TranslateService);

  @Selector()
  static setting(state: SettingStateModel) {
    if (state && state.setting) {
      return state.setting;
    }
  }

  @Selector()
  static selectedCurrency(state: SettingStateModel) {
    return state.selectedCurrency;
  }

  @Action(GetSettingOptionAction)
  getSettingOptions(ctx: StateContext<SettingStateModel>) {
    return this.settingService.getSettingOption().pipe(
      tap({
        next: result => {
          if (result && result.values) {
            const state = ctx.getState();

            if (
              this.store.selectSnapshot(state => state.language && state.language.defaultLanguage)
            ) {
              const lang = this.store.selectSnapshot(
                state => state.language && state.language.defaultLanguage,
              );
              this.translate.use(lang?.locale);
            } else {
              this.translate.use(result?.values?.general.default_language?.locale);
              this.store.dispatch(
                new SetDefaultLanguageAction(result?.values?.general.default_language),
              );
            }

            if (!state.selectedCurrency && result?.values?.general) {
              state.selectedCurrency = result?.values?.general.default_currency;
            }

            if (state.selectedCurrency) {
              if (
                state.selectedCurrency.id == result?.values?.general.default_currency.id &&
                state.selectedCurrency.exchange_rate !=
                  result?.values?.general.default_currency.exchange_rate
              ) {
                state.selectedCurrency = result?.values?.general.default_currency;
              }
            }

            ctx.patchState({
              ...state,
              setting: result.values,
            });
          }
        },
        error: err => {
          throw new Error(err?.error?.message);
        },
      }),
    );
  }

  @Action(SelectedCurrencyAction)
  selectedCurrency(ctx: StateContext<SettingStateModel>, action: SelectedCurrencyAction) {
    const state = ctx.getState();
    ctx.patchState({
      ...state,
      selectedCurrency: action.payload,
    });
  }
}
