import { Component, inject, OnInit, OnDestroy, signal } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormBuilder, FormGroup, ReactiveFormsModule, FormsModule, 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 { DatePickerModule } from 'primeng/datepicker';
import { TextareaModule } from 'primeng/textarea';
import { TooltipModule } from 'primeng/tooltip';
import { MessageService, ConfirmationService } from 'primeng/api';
import { PageHeaderComponent, DataTableComponent, FormDialogComponent, TableColumn } from '../../shared';
import { Subscription } from 'rxjs';
import { FixedAssetService } from '../../core/services/fixed-asset.service';
import { AssetCategoryService } from '../../core/services/asset-category.service';
import { FixedAsset } from '../../core/models/fixed-asset.model';
import { AssetCategory } from '../../core/models/asset-category.model';
import { map } from 'rxjs/operators';
import { selectAllBranches, BranchesActions, selectAllPartners, PartnersActions, selectUser } from '../../core/store';

@Component({
  selector: 'app-fixed-assets',
  standalone: true,
  imports: [
    CommonModule, ReactiveFormsModule, FormsModule, TranslateModule,
    TableModule, ButtonModule, DialogModule, InputTextModule, InputNumberModule,
    SelectModule, TagModule, ToastModule, ConfirmDialogModule,
    DatePickerModule, TextareaModule, TooltipModule,
    PageHeaderComponent, DataTableComponent, FormDialogComponent,
  ],
  providers: [MessageService, ConfirmationService],
  templateUrl: './fixed-assets.component.html',
  styleUrl: './fixed-assets.component.scss',
})
export class FixedAssetsComponent implements OnInit, OnDestroy {
  readonly columns: TableColumn[] = [
    { field: 'code', header: 'FIXED_ASSETS.CODE' },
    { field: 'name', header: 'FIXED_ASSETS.NAME' },
    { field: 'category', header: 'FIXED_ASSETS.CATEGORY' },
    { field: 'purchase_cost', header: 'FIXED_ASSETS.PURCHASE_COST' },
    { field: 'current_value', header: 'FIXED_ASSETS.CURRENT_VALUE' },
    { field: 'status', header: 'COMMON.STATUS' },
    { field: 'actions', header: 'COMMON.ACTIONS' },
  ];

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

  items = signal<FixedAsset[]>([]);
  tableData = signal<FixedAsset[]>([]);
  totalRecords = signal(0);
  tableLoading = signal(false);
  first = 0;
  rows = 25;
  categories = signal<AssetCategory[]>([]);
  loading = signal(true);
  dialogVisible = signal(false);
  editing = signal<FixedAsset | null>(null);
  saving = signal(false);
  detailVisible = signal(false);
  detailAsset = signal<FixedAsset | null>(null);
  sellDialogVisible = signal(false);
  sellAsset = signal<FixedAsset | null>(null);
  depDialogVisible = signal(false);
  statusFilter = signal<string>('');

  private userBranchIds: number[] = [];
  branches$ = this.store.select(selectAllBranches).pipe(
    map(branches => {
      if (!this.userBranchIds.length) return branches;
      return branches.filter(b => this.userBranchIds.includes(b.id));
    })
  );
  partners$ = this.store.select(selectAllPartners);

  form!: FormGroup;
  sellForm!: FormGroup;
  depForm!: FormGroup;
  depMethodOptions: any[] = [];
  statusOptions: any[] = [];
  private langSub!: Subscription;

  ngOnInit(): void {
    this.initForms();
    this.buildOptions();
    this.langSub = this.translate.onLangChange.subscribe(() => this.buildOptions());
    this.loadPage();
    this.loadCategories();
    this.store.select(selectUser).subscribe(user => {
      this.userBranchIds = user?.branches?.map(b => b.id) || [];
    });
    this.store.dispatch(BranchesActions.loadBranches({}));
    this.store.dispatch(PartnersActions.loadPartners({}));
  }

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

  private buildOptions(): void {
    this.depMethodOptions = [
      { label: this.translate.instant('ASSET_CATEGORIES.METHOD_STRAIGHT_LINE'), value: 'straight_line' },
      { label: this.translate.instant('ASSET_CATEGORIES.METHOD_DECLINING_BALANCE'), value: 'declining_balance' },
    ];
    this.statusOptions = [
      { label: this.translate.instant('COMMON.ALL'), value: '' },
      { label: this.translate.instant('COMMON.ACTIVE'), value: 'active' },
      { label: this.translate.instant('FIXED_ASSETS.STATUS_DISPOSED'), value: 'disposed' },
      { label: this.translate.instant('FIXED_ASSETS.STATUS_SOLD'), value: 'sold' },
    ];
  }

  private initForms(): void {
    this.form = this.fb.group({
      asset_category_id: [null, Validators.required],
      code: ['', Validators.required],
      name_ar: ['', Validators.required],
      name: [''],
      description: [''],
      serial_number: [''],
      location: [''],
      purchase_date: [null, Validators.required],
      in_service_date: [null],
      purchase_cost: [0, [Validators.required, Validators.min(0)]],
      salvage_value: [0],
      useful_life_months: [60, Validators.required],
      depreciation_method: ['straight_line', Validators.required],
      branch_id: [null],
      partner_id: [null],
      notes: [''],
    });
    this.sellForm = this.fb.group({ sale_amount: [0, [Validators.required, Validators.min(0)]] });
    this.depForm = this.fb.group({ period_date: [null, Validators.required] });
  }

  private loadCategories(): void {
    this.catService.list(1, 100).subscribe({
      next: (res) => this.categories.set(res.data || []),
    });
  }

  loadPage(page = 1, perPage = this.rows): void {
    this.tableLoading.set(true);
    this.loading.set(true);
    this.service.list(page, perPage, this.statusFilter() || undefined).subscribe({
      next: (res) => {
        this.tableData.set(res.data || []);
        this.totalRecords.set(res.meta?.total || 0);
        this.tableLoading.set(false);
        this.loading.set(false);
      },
      error: () => { this.tableLoading.set(false); this.loading.set(false); },
    });
  }

  onPageChange(event: any): void {
    this.first = event.first;
    this.rows = event.rows;
    const page = Math.floor(event.first / event.rows) + 1;
    this.loadPage(page, event.rows);
  }

  private loadData(): void {
    this.loadPage(Math.floor(this.first / this.rows) + 1, this.rows);
  }

  onStatusFilter(status: string): void {
    this.statusFilter.set(status);
    this.first = 0;
    this.loadPage(1, this.rows);
  }

  openNew(): void {
    this.editing.set(null);
    this.form.reset({ depreciation_method: 'straight_line', useful_life_months: 60, purchase_cost: 0, salvage_value: 0 });
    this.dialogVisible.set(true);
  }

  edit(item: FixedAsset): void {
    this.editing.set(item);
    this.form.patchValue({
      ...item,
      purchase_date: item.purchase_date ? new Date(item.purchase_date) : null,
      in_service_date: item.in_service_date ? new Date(item.in_service_date) : null,
    });
    this.dialogVisible.set(true);
  }

  viewDetail(item: FixedAsset): void {
    this.service.getById(item.id).subscribe({
      next: (res) => { this.detailAsset.set(res.data); this.detailVisible.set(true); },
      error: (err) => this.messageService.add({ severity: 'error', summary: this.translate.instant('COMMON.ERROR'), detail: err.error?.message || 'Failed' }),
    });
  }

  delete(item: FixedAsset): void {
    this.confirmationService.confirm({
      message: this.translate.instant('FIXED_ASSETS.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('FIXED_ASSETS.DELETE_SUCCESS') });
          },
          error: (err) => this.messageService.add({ severity: 'error', summary: this.translate.instant('COMMON.ERROR'), detail: err.error?.message || 'Failed' }),
        });
      },
    });
  }

  dispose(item: FixedAsset): void {
    this.confirmationService.confirm({
      message: this.translate.instant('FIXED_ASSETS.CONFIRM_DISPOSE'),
      header: this.translate.instant('COMMON.CONFIRM'),
      accept: () => {
        this.service.dispose(item.id).subscribe({
          next: () => {
            this.loadData();
            this.messageService.add({ severity: 'success', summary: this.translate.instant('COMMON.SUCCESS'), detail: this.translate.instant('FIXED_ASSETS.DISPOSE_SUCCESS') });
          },
          error: (err) => this.messageService.add({ severity: 'error', summary: this.translate.instant('COMMON.ERROR'), detail: err.error?.message || 'Failed' }),
        });
      },
    });
  }

  openSell(item: FixedAsset): void {
    this.sellAsset.set(item);
    this.sellForm.reset({ sale_amount: item.current_value });
    this.sellDialogVisible.set(true);
  }

  onSell(): void {
    if (!this.sellForm.valid) return;
    this.saving.set(true);
    this.service.sell(this.sellAsset()!.id, this.sellForm.value.sale_amount).subscribe({
      next: () => {
        this.saving.set(false);
        this.sellDialogVisible.set(false);
        this.loadData();
        this.messageService.add({ severity: 'success', summary: this.translate.instant('COMMON.SUCCESS'), detail: this.translate.instant('FIXED_ASSETS.SELL_SUCCESS') });
      },
      error: (err) => {
        this.saving.set(false);
        this.messageService.add({ severity: 'error', summary: this.translate.instant('COMMON.ERROR'), detail: err.error?.message || 'Failed' });
      },
    });
  }

  openDepreciation(): void {
    this.depForm.reset();
    this.depDialogVisible.set(true);
  }

  onRunDepreciation(): void {
    if (!this.depForm.valid) return;
    this.saving.set(true);
    const date = this.depForm.value.period_date;
    const dateStr = date instanceof Date ? date.toISOString().split('T')[0] : date;
    this.service.runDepreciation(dateStr).subscribe({
      next: () => {
        this.saving.set(false);
        this.depDialogVisible.set(false);
        this.loadData();
        this.messageService.add({ severity: 'success', summary: this.translate.instant('COMMON.SUCCESS'), detail: this.translate.instant('FIXED_ASSETS.DEPRECIATION_SUCCESS') });
      },
      error: (err) => {
        this.saving.set(false);
        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,
      purchase_date: val.purchase_date instanceof Date ? val.purchase_date.toISOString().split('T')[0] : val.purchase_date,
      in_service_date: val.in_service_date instanceof Date ? val.in_service_date.toISOString().split('T')[0] : val.in_service_date,
    };

    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() ? 'FIXED_ASSETS.UPDATE_SUCCESS' : 'FIXED_ASSETS.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.loadPage(Math.floor(this.first / this.rows) + 1, this.rows); }

  getStatusSeverity(status: string): 'success' | 'info' | 'warn' | 'danger' | 'secondary' | 'contrast' {
    switch (status) {
      case 'active': return 'success';
      case 'disposed': return 'warn';
      case 'sold': return 'info';
      default: return 'secondary';
    }
  }
}
