import { Component, inject, OnInit, OnDestroy, signal } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormBuilder, FormGroup, FormArray, ReactiveFormsModule, Validators } from '@angular/forms';
import { Store } from '@ngrx/store';
import { TranslateModule, TranslateService } from '@ngx-translate/core';
import { TableModule } from 'primeng/table';
import { ButtonModule } from 'primeng/button';
import { DialogModule } from 'primeng/dialog';
import { InputTextModule } from 'primeng/inputtext';
import { InputNumberModule } from 'primeng/inputnumber';
import { SelectModule } from 'primeng/select';
import { TagModule } from 'primeng/tag';
import { ToastModule } from 'primeng/toast';
import { ConfirmDialogModule } from 'primeng/confirmdialog';
import { TooltipModule } from 'primeng/tooltip';
import { ToggleSwitchModule } from 'primeng/toggleswitch';
import { DatePickerModule } from 'primeng/datepicker';
import { MessageService, ConfirmationService } from 'primeng/api';
import { PageHeaderComponent, DataTableComponent, FormDialogComponent, TableColumn } from '../../shared';
import { Subscription } from 'rxjs';
import { AllocationRuleService } from '../../core/services/allocation-rule.service';
import { AllocationRule } from '../../core/models/allocation-rule.model';
import { AccountsActions, selectAllAccounts, CostCentersActions, selectAllCostCenters } from '../../core/store';

@Component({
  selector: 'app-allocation-rules',
  standalone: true,
  imports: [
    CommonModule, ReactiveFormsModule, TranslateModule,
    TableModule, ButtonModule, DialogModule, InputTextModule, InputNumberModule,
    SelectModule, TagModule, ToastModule, ConfirmDialogModule, TooltipModule,
    ToggleSwitchModule, DatePickerModule,
    PageHeaderComponent, DataTableComponent, FormDialogComponent,
  ],
  providers: [MessageService, ConfirmationService],
  templateUrl: './allocation-rules.component.html',
  styleUrl: './allocation-rules.component.scss',
})
export class AllocationRulesComponent implements OnInit, OnDestroy {
  readonly columns: TableColumn[] = [
    { field: 'name', header: 'ALLOCATION_RULES.NAME' },
    { field: 'source_cc', header: 'ALLOCATION_RULES.SOURCE_CC' },
    { field: 'method', header: 'ALLOCATION_RULES.METHOD' },
    { field: 'status', header: 'COMMON.STATUS' },
    { field: 'actions', header: 'COMMON.ACTIONS' },
  ];

  private fb = inject(FormBuilder);
  private store = inject(Store);
  private service = inject(AllocationRuleService);
  private messageService = inject(MessageService);
  private confirmationService = inject(ConfirmationService);
  private translate = inject(TranslateService);

  items = signal<AllocationRule[]>([]);
  loading = signal(true);
  dialogVisible = signal(false);
  editing = signal<AllocationRule | null>(null);
  saving = signal(false);
  simDialogVisible = signal(false);
  simResult = signal<any>(null);

  accounts$ = this.store.select(selectAllAccounts);
  costCenters$ = this.store.select(selectAllCostCenters);

  form!: FormGroup;
  simForm!: FormGroup;
  methodOptions: any[] = [];
  private langSub!: Subscription;
  private simRuleId = 0;

  ngOnInit(): void {
    this.initForms();
    this.buildOptions();
    this.langSub = this.translate.onLangChange.subscribe(() => this.buildOptions());
    this.loadData();
    this.store.dispatch(AccountsActions.loadAccounts({}));
    this.store.dispatch(CostCentersActions.loadCostCenters({}));
  }

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

  private buildOptions(): void {
    this.methodOptions = [
      { label: this.translate.instant('ALLOCATION_RULES.METHOD_FIXED'), value: 'fixed_percentage' },
      { label: this.translate.instant('ALLOCATION_RULES.METHOD_DIRECT'), value: 'direct_cost' },
      { label: this.translate.instant('ALLOCATION_RULES.METHOD_MANUAL'), value: 'manual' },
    ];
  }

  private initForms(): void {
    this.form = this.fb.group({
      name_ar: ['', Validators.required],
      name: [''],
      description: [''],
      source_cost_center_id: [null, Validators.required],
      source_account_id: [null, Validators.required],
      method: ['fixed_percentage', Validators.required],
      is_active: [true],
      lines: this.fb.array([]),
    });
    this.simForm = this.fb.group({
      period_start: [null, Validators.required],
      period_end: [null, Validators.required],
    });
  }

  get lines(): FormArray { return this.form.get('lines') as FormArray; }

  addLine(): void {
    this.lines.push(this.fb.group({
      target_cost_center_id: [null, Validators.required],
      percentage: [0, [Validators.required, Validators.min(0), Validators.max(100)]],
    }));
  }

  removeLine(i: number): void { this.lines.removeAt(i); }

  private loadData(): void {
    this.loading.set(true);
    this.service.list(1, 100).subscribe({
      next: (res) => { this.items.set(res.data || []); this.loading.set(false); },
      error: () => this.loading.set(false),
    });
  }

  openNew(): void {
    this.editing.set(null);
    this.form.reset({ method: 'fixed_percentage', is_active: true });
    this.lines.clear();
    this.addLine();
    this.dialogVisible.set(true);
  }

  edit(item: AllocationRule): void {
    this.editing.set(item);
    this.form.patchValue({
      name_ar: item.name_ar, name: item.name, description: item.description,
      source_cost_center_id: item.source_cost_center_id, source_account_id: item.source_account_id,
      method: item.method, is_active: item.is_active,
    });
    this.lines.clear();
    (item.lines || []).forEach(l => this.lines.push(this.fb.group({
      target_cost_center_id: [l.target_cost_center_id, Validators.required],
      percentage: [l.percentage, [Validators.required, Validators.min(0), Validators.max(100)]],
    })));
    if (this.lines.length === 0) this.addLine();
    this.dialogVisible.set(true);
  }

  delete(item: AllocationRule): void {
    this.confirmationService.confirm({
      message: this.translate.instant('ALLOCATION_RULES.CONFIRM_DELETE'),
      header: this.translate.instant('COMMON.CONFIRM'),
      acceptButtonStyleClass: 'p-button-danger',
      accept: () => {
        this.service.delete(item.id).subscribe({
          next: () => {
            this.loadData();
            this.messageService.add({ severity: 'success', summary: this.translate.instant('COMMON.SUCCESS'), detail: this.translate.instant('ALLOCATION_RULES.DELETE_SUCCESS') });
          },
          error: (err) => this.messageService.add({ severity: 'error', summary: this.translate.instant('COMMON.ERROR'), detail: err.error?.message || 'Failed' }),
        });
      },
    });
  }

  openSimulate(item: AllocationRule): void {
    this.simRuleId = item.id;
    this.simResult.set(null);
    this.simForm.reset();
    this.simDialogVisible.set(true);
  }

  onSimulate(): void {
    if (!this.simForm.valid) return;
    this.saving.set(true);
    const v = this.simForm.value;
    const start = v.period_start instanceof Date ? v.period_start.toISOString().split('T')[0] : v.period_start;
    const end = v.period_end instanceof Date ? v.period_end.toISOString().split('T')[0] : v.period_end;
    this.service.simulate(this.simRuleId, start, end).subscribe({
      next: (res) => { this.saving.set(false); this.simResult.set(res.data || res); },
      error: (err) => { this.saving.set(false); this.messageService.add({ severity: 'error', summary: this.translate.instant('COMMON.ERROR'), detail: err.error?.message || 'Failed' }); },
    });
  }

  onExecute(item: AllocationRule): void {
    this.confirmationService.confirm({
      message: this.translate.instant('ALLOCATION_RULES.CONFIRM_EXECUTE'),
      header: this.translate.instant('COMMON.CONFIRM'),
      accept: () => {
        const today = new Date();
        const start = new Date(today.getFullYear(), today.getMonth(), 1).toISOString().split('T')[0];
        const end = today.toISOString().split('T')[0];
        this.service.execute(item.id, start, end).subscribe({
          next: () => this.messageService.add({ severity: 'success', summary: this.translate.instant('COMMON.SUCCESS'), detail: this.translate.instant('ALLOCATION_RULES.EXECUTE_SUCCESS') }),
          error: (err) => this.messageService.add({ severity: 'error', summary: this.translate.instant('COMMON.ERROR'), detail: err.error?.message || 'Failed' }),
        });
      },
    });
  }

  onSave(): void {
    if (!this.form.valid) { this.form.markAllAsTouched(); return; }
    this.saving.set(true);
    const val = this.form.value;
    const data = { ...val, name: val.name || val.name_ar };

    const obs = this.editing()
      ? this.service.update(this.editing()!.id, data)
      : this.service.create(data);

    obs.subscribe({
      next: () => {
        this.saving.set(false);
        this.dialogVisible.set(false);
        this.loadData();
        this.messageService.add({ severity: 'success', summary: this.translate.instant('COMMON.SUCCESS'),
          detail: this.translate.instant(this.editing() ? 'ALLOCATION_RULES.UPDATE_SUCCESS' : 'ALLOCATION_RULES.CREATE_SUCCESS') });
      },
      error: (err) => {
        this.saving.set(false);
        this.messageService.add({ severity: 'error', summary: this.translate.instant('COMMON.ERROR'), detail: err.error?.message || 'Failed' });
      },
    });
  }

  retry(): void { this.loadData(); }
}
