import { Component, inject, OnInit, OnDestroy, signal } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormBuilder, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';
import { Store } from '@ngrx/store';
import { TranslateModule, TranslateService } from '@ngx-translate/core';
import { Subscription } from 'rxjs';
import { take } from 'rxjs/operators';
import { TableModule } from 'primeng/table';
import { ButtonModule } from 'primeng/button';
import { InputNumberModule } from 'primeng/inputnumber';
import { SelectModule } from 'primeng/select';
import { DatePickerModule } from 'primeng/datepicker';
import { ToastModule } from 'primeng/toast';
import { MessageService } from 'primeng/api';
import { PageHeaderComponent, DataTableComponent, FormDialogComponent, TableColumn } from '../../shared';
import {
  ExchangeRatesActions,
  selectAllExchangeRates,
  selectExchangeRatesLoading,
  selectExchangeRatesSaving,
  selectExchangeRatesError,
  CurrenciesActions,
  selectAllCurrencies,
} from '../../core/store';
import { ExchangeRate } from '../../core/models/exchange-rate.model';
import { Currency } from '../../core/models/currency.model';

@Component({
  selector: 'app-exchange-rates',
  standalone: true,
  imports: [
    CommonModule,
    ReactiveFormsModule,
    TranslateModule,
    TableModule,
    ButtonModule,
    InputNumberModule,
    SelectModule,
    DatePickerModule,
    ToastModule,
    PageHeaderComponent,
    DataTableComponent,
    FormDialogComponent,
  ],
  providers: [MessageService],
  templateUrl: './exchange-rates.component.html',
  styleUrl: './exchange-rates.component.scss',
})
export class ExchangeRatesComponent implements OnInit, OnDestroy {
  private fb = inject(FormBuilder);
  private store = inject(Store);
  private messageService = inject(MessageService);
  private translate = inject(TranslateService);
  private langSub!: Subscription;

  readonly columns: TableColumn[] = [
    { field: 'from_currency', header: 'EXCHANGE_RATES.FROM_CURRENCY' },
    { field: 'to_currency', header: 'EXCHANGE_RATES.TO_CURRENCY' },
    { field: 'rate', header: 'EXCHANGE_RATES.RATE', sortable: true },
    { field: 'effective_date', header: 'EXCHANGE_RATES.EFFECTIVE_DATE', sortable: true },
  ];

  exchangeRates$ = this.store.select(selectAllExchangeRates);
  loading$ = this.store.select(selectExchangeRatesLoading);
  saving$ = this.store.select(selectExchangeRatesSaving);
  error$ = this.store.select(selectExchangeRatesError);
  currencies$ = this.store.select(selectAllCurrencies);

  dialogVisible = signal(false);
  rateForm!: FormGroup;

  ngOnInit(): void {
    this.initForm();
    this.langSub = this.translate.onLangChange.subscribe(() => {});
    this.store.dispatch(ExchangeRatesActions.loadExchangeRates({}));
    this.store.dispatch(CurrenciesActions.loadCurrencies({}));
  }

  ngOnDestroy(): void {
    this.langSub?.unsubscribe();
  }

  private initForm(): void {
    this.rateForm = this.fb.group({
      from_currency_id: [null, Validators.required],
      to_currency_id: [null, Validators.required],
      rate: [1, [Validators.required, Validators.min(0.000001)]],
      effective_date: [new Date(), Validators.required],
    });
  }

  openNew(): void {
    this.rateForm.reset({
      rate: 1,
      effective_date: new Date(),
    });
    this.dialogVisible.set(true);
  }

  onSave(): void {
    if (this.rateForm.valid) {
      const formValue = this.rateForm.value;
      const data = {
        from_currency_id: formValue.from_currency_id,
        to_currency_id: formValue.to_currency_id,
        rate: formValue.rate,
        effective_date: this.formatDate(formValue.effective_date),
      };

      this.store.dispatch(ExchangeRatesActions.createExchangeRate({ exchangeRate: data }));

      const sub = this.store.select(selectExchangeRatesSaving).subscribe((saving) => {
        if (!saving) {
          sub.unsubscribe();
          this.store.select(selectExchangeRatesError).pipe(take(1)).subscribe((error) => {
            if (error) {
              this.messageService.add({ severity: 'error', summary: this.translate.instant('COMMON.ERROR'), detail: error });
            } else {
              this.dialogVisible.set(false);
              this.messageService.add({
                severity: 'success',
                summary: this.translate.instant('COMMON.SUCCESS'),
                detail: this.translate.instant('EXCHANGE_RATES.CREATE_SUCCESS'),
              });
            }
          });
        }
      });
    } else {
      this.rateForm.markAllAsTouched();
    }
  }

  retry(): void {
    this.store.dispatch(ExchangeRatesActions.loadExchangeRates({ forceReload: true }));
  }

  private formatDate(date: Date): string {
    const y = date.getFullYear();
    const m = String(date.getMonth() + 1).padStart(2, '0');
    const d = String(date.getDate()).padStart(2, '0');
    return `${y}-${m}-${d}`;
  }

  getCurrencyCode(currencyId: number, currencies: Currency[]): string {
    const c = currencies.find(curr => curr.id === currencyId);
    return c ? c.code : '';
  }
}
