import { Component, inject, OnInit, 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 { take } from 'rxjs/operators';
import { TableModule } from 'primeng/table';
import { ButtonModule } from 'primeng/button';
import { InputTextModule } from 'primeng/inputtext';
import { SelectModule } from 'primeng/select';
import { MultiSelectModule } from 'primeng/multiselect';
import { ToggleSwitchModule } from 'primeng/toggleswitch';
import { TagModule } from 'primeng/tag';
import { ToastModule } from 'primeng/toast';
import { ConfirmDialogModule } from 'primeng/confirmdialog';
import { MessageService, ConfirmationService } from 'primeng/api';
import { PageHeaderComponent, DataTableComponent, FormDialogComponent, TableColumn } from '../../shared';
import {
  BankAccountsActions, selectAllBankAccounts, selectBankAccountsLoading,
  selectBankAccountsSaving, selectBankAccountsError,
  AccountsActions, selectAllAccounts,
  CurrenciesActions, selectAllCurrencies,
  BranchesActions, selectAllBranches,
} from '../../core/store';
import { BankAccount } from '../../core/models/bank-account.model';
import { Account } from '../../core/models/account.model';
import { HttpClient } from '@angular/common/http';
import { environment } from '../../../environments/environment';

@Component({
  selector: 'app-bank-accounts',
  standalone: true,
  imports: [
    CommonModule, ReactiveFormsModule, TranslateModule,
    TableModule, ButtonModule, InputTextModule,
    SelectModule, MultiSelectModule, ToggleSwitchModule, TagModule, ToastModule,
    ConfirmDialogModule,
    PageHeaderComponent, DataTableComponent, FormDialogComponent,
  ],
  providers: [MessageService, ConfirmationService],
  templateUrl: './bank-accounts.component.html',
  styleUrl: './bank-accounts.component.scss',
})
export class BankAccountsComponent implements OnInit {
  private fb = inject(FormBuilder);
  private store = inject(Store);
  private messageService = inject(MessageService);
  private confirmationService = inject(ConfirmationService);
  private translate = inject(TranslateService);
  private http = inject(HttpClient);

  readonly columns: TableColumn[] = [
    { field: 'bank_name', header: 'BANK_ACCOUNTS.BANK_NAME' },
    { field: 'account_number', header: 'BANK_ACCOUNTS.ACCOUNT_NUMBER' },
    { field: 'iban', header: 'BANK_ACCOUNTS.IBAN' },
    { field: 'account', header: 'BANK_ACCOUNTS.LINKED_ACCOUNT' },
    { field: 'balance', header: 'PETTY_CASH.CURRENT_BALANCE' },
    { field: 'currency', header: 'BANK_ACCOUNTS.CURRENCY' },
    { field: 'branches', header: 'BANK_ACCOUNTS.BRANCHES' },
    { field: 'status', header: 'COMMON.STATUS' },
    { field: 'actions', header: 'COMMON.ACTIONS' },
  ];

  items = signal<(BankAccount & { journal_balance: number })[]>([]);
  private rawItems: BankAccount[] = [];
  private balanceMap: Record<number, number> = {};
  loading$ = this.store.select(selectBankAccountsLoading);
  saving$ = this.store.select(selectBankAccountsSaving);
  error$ = this.store.select(selectBankAccountsError);
  accounts$ = this.store.select(selectAllAccounts);
  currencies$ = this.store.select(selectAllCurrencies);
  branches$ = this.store.select(selectAllBranches);

  dialogVisible = signal(false);
  editing = signal<BankAccount | null>(null);
  form!: FormGroup;
  detailAccounts = signal<Account[]>([]);

  ngOnInit(): void {
    this.form = this.fb.group({
      bank_name: ['', Validators.required],
      bank_name_en: [''],
      bank_name_ar: [''],
      account_number: ['', Validators.required],
      account_id: [null],
      iban: [''],
      swift_code: [''],
      currency_id: [null],
      branch_ids: [[]],
      is_active: [true],
    });
    this.store.dispatch(BankAccountsActions.loadBankAccounts({}));
    this.store.dispatch(AccountsActions.loadAccounts({}));
    this.store.dispatch(CurrenciesActions.loadCurrencies({}));
    this.store.dispatch(BranchesActions.loadBranches({}));
    this.store.select(selectAllBankAccounts).subscribe(list => {
      this.rawItems = list;
      this.mergeBalances();
    });
    this.loadAccountBalances();
    this.accounts$.subscribe(accounts => {
      this.detailAccounts.set(accounts.filter(a => a.account_type === 'detail'));
    });
  }

  openNew(): void {
    this.editing.set(null);
    this.form.reset({ is_active: true, branch_ids: [] });
    this.dialogVisible.set(true);
  }

  edit(item: BankAccount): void {
    this.editing.set(item);
    this.form.patchValue({
      ...item,
      branch_ids: (item.branches || []).map(b => b.id),
    });
    this.dialogVisible.set(true);
  }

  delete(item: BankAccount): void {
    this.confirmationService.confirm({
      message: this.translate.instant('BANK_ACCOUNTS.CONFIRM_DELETE'),
      header: this.translate.instant('COMMON.CONFIRM'),
      icon: 'pi pi-exclamation-triangle',
      acceptButtonStyleClass: 'p-button-danger',
      accept: () => {
        this.store.dispatch(BankAccountsActions.deleteBankAccount({ id: item.id }));
        const sub = this.store.select(selectBankAccountsSaving).subscribe(saving => {
          if (!saving) {
            sub.unsubscribe();
            this.store.select(selectBankAccountsError).pipe(take(1)).subscribe(error => {
              this.messageService.add(error
                ? { severity: 'error', summary: this.translate.instant('COMMON.ERROR'), detail: error }
                : { severity: 'success', summary: this.translate.instant('COMMON.SUCCESS'), detail: this.translate.instant('BANK_ACCOUNTS.DELETE_SUCCESS') });
            });
          }
        });
      },
    });
  }

  onSave(): void {
    if (this.form.valid) {
      const data = this.form.value;
      if (this.editing()) {
        this.store.dispatch(BankAccountsActions.updateBankAccount({ id: this.editing()!.id, bankAccount: data }));
      } else {
        this.store.dispatch(BankAccountsActions.createBankAccount({ bankAccount: data }));
      }
      const sub = this.store.select(selectBankAccountsSaving).subscribe(saving => {
        if (!saving) {
          sub.unsubscribe();
          this.store.select(selectBankAccountsError).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(this.editing() ? 'BANK_ACCOUNTS.UPDATE_SUCCESS' : 'BANK_ACCOUNTS.CREATE_SUCCESS') });
            }
          });
        }
      });
    } else {
      this.form.markAllAsTouched();
    }
  }

  private mergeBalances(): void {
    this.items.set(this.rawItems.map(ba => ({
      ...ba,
      journal_balance: this.balanceMap[ba.account_id] ?? 0,
    })));
  }

  loadAccountBalances(): void {
    this.http.get<any>(`${environment.apiUrl}/accounting/reports/trial-balance`).subscribe({
      next: (res) => {
        this.balanceMap = {};
        for (const row of res.data || []) {
          this.balanceMap[row.account_id] = Number(row.balance) || 0;
        }
        this.mergeBalances();
      },
      error: () => {},
    });
  }

  retry(): void {
    this.store.dispatch(BankAccountsActions.loadBankAccounts({ forceReload: true }));
    this.loadAccountBalances();
  }
}
