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 { Subscription } from 'rxjs';
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 { ToggleSwitchModule } from 'primeng/toggleswitch';
import { DatePickerModule } from 'primeng/datepicker';
import { TextareaModule } from 'primeng/textarea';
import { MessageService, ConfirmationService } from 'primeng/api';
import { PageHeaderComponent, DataTableComponent, FormDialogComponent, TableColumn } from '../../shared';
import { PartnerService } from '../../core/services/partner.service';
import { AccountService } from '../../core/services/account.service';
import { SettingService } from '../../core/services/setting.service';
import {
  PartnerCategoriesActions,
  selectAllPartnerCategories,
  AccountsActions,
  selectAllAccounts,
} from '../../core/store';
import { Partner, PartnerContact, PartnerAddress } from '../../core/models/partner.model';
import { Account } from '../../core/models/account.model';
import { JournalEntryService } from '../../core/services/journal-entry.service';
import { HttpClient } from '@angular/common/http';
import { environment } from '../../../environments/environment';

@Component({
  selector: 'app-partners',
  standalone: true,
  imports: [
    CommonModule,
    ReactiveFormsModule,
    FormsModule,
    TranslateModule,
    TableModule,
    ButtonModule,
    DialogModule,
    InputTextModule,
    InputNumberModule,
    SelectModule,
    TagModule,
    ToastModule,
    ConfirmDialogModule,
    ToggleSwitchModule,
    DatePickerModule,
    TextareaModule,
    PageHeaderComponent,
    DataTableComponent,
    FormDialogComponent,
  ],
  providers: [MessageService, ConfirmationService],
  templateUrl: './partners.component.html',
  styleUrl: './partners.component.scss',
})
export class PartnersComponent implements OnInit, OnDestroy {
  private fb = inject(FormBuilder);
  private store = inject(Store);
  private messageService = inject(MessageService);
  private confirmationService = inject(ConfirmationService);
  private translate = inject(TranslateService);
  private partnerService = inject(PartnerService);
  private accountService = inject(AccountService);
  private settingService = inject(SettingService);
  private http = inject(HttpClient);
  private journalEntryService = inject(JournalEntryService);
  private langSub!: Subscription;

  // Default parent accounts from settings
  private defaultClientParentId: number | null = null;
  private defaultSupplierParentId: number | null = null;
  private allAccounts = signal<Account[]>([]);

  readonly columns: TableColumn[] = [
    { field: 'code', header: 'PARTNERS.CODE', sortable: true },
    { field: 'name_ar', header: 'PARTNERS.NAME_AR', sortable: true },
    { field: 'type', header: 'PARTNERS.TYPE' },
    { field: 'role', header: 'PARTNERS.ROLE' },
    { field: 'balance', header: 'PETTY_CASH.CURRENT_BALANCE' },
    { field: 'phone', header: 'PARTNERS.PHONE' },
    { field: 'status', header: 'COMMON.STATUS' },
    { field: 'actions', header: 'COMMON.ACTIONS' },
  ];

  /** Account balances from trial balance for partner AR/AP accounts */
  accountBalanceMap: Record<number, number> = {};

  categories$ = this.store.select(selectAllPartnerCategories);
  accounts$ = this.store.select(selectAllAccounts);
  savingPartner = signal(false);

  // Server-side pagination
  tableData = signal<Partner[]>([]);
  totalRecords = signal(0);
  tableLoading = signal(false);
  first = 0;
  rows = 25;

  dialogVisible = signal(false);
  editingPartner = signal<Partner | null>(null);
  partnerForm!: FormGroup;

  // Contacts
  contacts = signal<PartnerContact[]>([]);
  contactForm!: FormGroup;
  contactDialogVisible = signal(false);
  editingContact = signal<PartnerContact | null>(null);

  // Addresses
  addresses = signal<PartnerAddress[]>([]);
  addressForm!: FormGroup;
  addressDialogVisible = signal(false);
  editingAddress = signal<PartnerAddress | null>(null);

  // Debt Changes
  debtChanges = signal<any[]>([]);
  debtDialogVisible = signal(false);
  debtForm!: FormGroup;
  debtPartner = signal<Partner | null>(null);

  typeOptions: any[] = [];
  classificationOptions: any[] = [];
  statusOptions: any[] = [];
  addressTypeOptions: any[] = [];

  ngOnInit(): void {
    this.initForm();
    this.initContactForm();
    this.initAddressForm();
    this.initDebtForm();
    this.buildOptions();
    this.langSub = this.translate.onLangChange.subscribe(() => this.buildOptions());
    this.loadPage();
    this.loadAccountBalances();
    this.store.dispatch(PartnerCategoriesActions.loadPartnerCategories({}));
    this.store.dispatch(AccountsActions.loadAccounts({}));
    this.accounts$.subscribe(a => this.allAccounts.set(a));
    // Load default parent account IDs for auto-creating partner accounts
    this.settingService.getByKey('accounting.default_client_account').subscribe({
      next: (res: any) => { const v = res?.data?.value ?? res?.value; this.defaultClientParentId = v && v !== '0' ? Number(v) : null; },
      error: () => {},
    });
    this.settingService.getByKey('accounting.default_supplier_account').subscribe({
      next: (res: any) => { const v = res?.data?.value ?? res?.value; this.defaultSupplierParentId = v && v !== '0' ? Number(v) : null; },
      error: () => {},
    });
  }

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

  private buildOptions(): void {
    this.typeOptions = [
      { label: this.translate.instant('PARTNERS.TYPE_INDIVIDUAL'), value: 'individual' },
      { label: this.translate.instant('PARTNERS.TYPE_COMPANY'), value: 'company' },
    ];
    this.classificationOptions = [
      { label: this.translate.instant('PARTNERS.CLASS_NORMAL'), value: 'normal' },
      { label: this.translate.instant('PARTNERS.CLASS_VIP'), value: 'vip' },
      { label: this.translate.instant('PARTNERS.CLASS_NEW'), value: 'new' },
      { label: this.translate.instant('PARTNERS.CLASS_STRATEGIC'), value: 'strategic' },
    ];
    this.statusOptions = [
      { label: this.translate.instant('COMMON.ACTIVE'), value: 'active' },
      { label: this.translate.instant('PARTNERS.STATUS_SUSPENDED'), value: 'suspended' },
    ];
    this.addressTypeOptions = [
      { label: this.translate.instant('PARTNERS.ADDR_BILLING'), value: 'billing' },
      { label: this.translate.instant('PARTNERS.ADDR_SHIPPING'), value: 'shipping' },
      { label: this.translate.instant('PARTNERS.ADDR_BOTH'), value: 'both' },
    ];
    this.debtTypeOptions = [
      { label: this.translate.instant('PARTNERS.DEBT_INCREASE'), value: 'increase' },
      { label: this.translate.instant('PARTNERS.DEBT_DECREASE'), value: 'decrease' },
    ];
    this.roleFilterOptions = [
      { label: this.translate.instant('COMMON.ALL'), value: null },
      { label: this.translate.instant('PARTNERS.CUSTOMER'), value: 'customer' },
      { label: this.translate.instant('PARTNERS.SUPPLIER'), value: 'supplier' },
    ];
  }

  // ─── Filters ───
  activeTypeFilter: string | null = null;
  activeStatusFilter: string | null = null;
  activeClassFilter: string | null = null;
  activeRoleFilter: string | null = null;

  get filteredPartners(): Partner[] {
    let result = [...this.tableData()];
    if (this.activeTypeFilter) result = result.filter(p => p.type === this.activeTypeFilter);
    if (this.activeStatusFilter) result = result.filter(p => p.status === this.activeStatusFilter);
    if (this.activeClassFilter) result = result.filter(p => p.classification === this.activeClassFilter);
    if (this.activeRoleFilter === 'customer') result = result.filter(p => p.is_customer);
    if (this.activeRoleFilter === 'supplier') result = result.filter(p => p.is_supplier);
    return result;
  }

  private initForm(): void {
    this.partnerForm = this.fb.group({
      code: [''],
      name_ar: ['', Validators.required],
      name_en: [''],
      type: ['company', Validators.required],
      classification: ['normal'],
      status: ['active'],
      is_customer: [true],
      is_supplier: [false],
      partner_category_id: [null],
      tax_number: [''],
      commercial_register: [''],
      email: [''],
      phone: [''],
      mobile: [''],
      fax: [''],
      website: [''],
      credit_limit: [0],
      payment_terms_days: [30],
      ar_account_id: [null],
      ap_account_id: [null],
      notes: [''],
    });
  }

  private initContactForm(): void {
    this.contactForm = this.fb.group({
      name: ['', Validators.required],
      name_ar: ['', Validators.required],
      position: [''],
      position_ar: [''],
      email: [''],
      phone: [''],
      mobile: [''],
      is_primary: [false],
    });
  }

  private initAddressForm(): void {
    this.addressForm = this.fb.group({
      address_type: ['billing', Validators.required],
      address_line_1: ['', Validators.required],
      address_line_2: [''],
      city: [''],
      governorate: [''],
      country_code: [''],
      postal_code: [''],
      is_default: [false],
    });
  }

  openNew(): void {
    this.editingPartner.set(null);
    this.contacts.set([]);
    this.addresses.set([]);
    this.partnerForm.reset({
      type: 'company',
      classification: 'normal',
      status: 'active',
      is_customer: true,
      is_supplier: false,
      credit_limit: 0,
      payment_terms_days: 30,
      ar_account_id: null,
      ap_account_id: null,
    });
    this.dialogVisible.set(true);
  }

  editPartner(partner: Partner): void {
    this.editingPartner.set(partner);
    this.partnerForm.patchValue({
      code: partner.code,
      name_ar: partner.name_ar,
      name_en: partner.name_en,
      type: partner.type,
      classification: partner.classification || 'normal',
      status: partner.status || 'active',
      is_customer: partner.is_customer,
      is_supplier: partner.is_supplier,
      partner_category_id: partner.partner_category_id,
      tax_number: partner.tax_number,
      commercial_register: partner.commercial_register,
      email: partner.email,
      phone: partner.phone,
      mobile: partner.mobile,
      fax: partner.fax,
      website: partner.website,
      credit_limit: parseFloat(partner.credit_limit) || 0,
      payment_terms_days: partner.payment_terms_days || 30,
      ar_account_id: partner.ar_account_id || null,
      ap_account_id: partner.ap_account_id || null,
      notes: partner.notes,
    });
    this.dialogVisible.set(true);
    this.loadContacts(partner.id);
    this.loadAddresses(partner.id);
  }

  // ─── Contacts ───

  private loadContacts(partnerId: number): void {
    this.partnerService.listContacts(partnerId).subscribe({
      next: (res) => this.contacts.set(res.data || []),
      error: () => this.contacts.set([]),
    });
  }

  openNewContact(): void {
    this.editingContact.set(null);
    this.contactForm.reset({ is_primary: false });
    this.contactDialogVisible.set(true);
  }

  editContact(contact: PartnerContact): void {
    this.editingContact.set(contact);
    this.contactForm.patchValue({
      name: contact.name,
      name_ar: contact.name_ar,
      position: contact.position,
      position_ar: contact.position_ar,
      email: contact.email,
      phone: contact.phone,
      mobile: contact.mobile,
      is_primary: contact.is_primary,
    });
    this.contactDialogVisible.set(true);
  }

  saveContact(): void {
    if (!this.contactForm.valid) { this.contactForm.markAllAsTouched(); return; }
    const partner = this.editingPartner();
    if (!partner) return;
    const data = this.contactForm.value;

    const obs = this.editingContact()
      ? this.partnerService.updateContact(this.editingContact()!.id, data)
      : this.partnerService.createContact(partner.id, data);

    obs.subscribe({
      next: () => {
        this.contactDialogVisible.set(false);
        this.loadContacts(partner.id);
        this.messageService.add({ severity: 'success', summary: this.translate.instant('COMMON.SUCCESS'), detail: 'Contact saved' });
      },
      error: (err) => this.messageService.add({ severity: 'error', summary: this.translate.instant('COMMON.ERROR'), detail: err.error?.message || 'Failed' }),
    });
  }

  deleteContact(contact: PartnerContact): void {
    const partner = this.editingPartner();
    if (!partner) return;
    this.confirmationService.confirm({
      message: `Delete contact "${contact.name}"?`,
      accept: () => {
        this.partnerService.deleteContact(contact.id).subscribe({
          next: () => {
            this.loadContacts(partner.id);
            this.messageService.add({ severity: 'success', summary: this.translate.instant('COMMON.SUCCESS'), detail: 'Contact deleted' });
          },
          error: (err) => this.messageService.add({ severity: 'error', summary: this.translate.instant('COMMON.ERROR'), detail: err.error?.message || 'Failed' }),
        });
      },
    });
  }

  // ─── Addresses ───

  private loadAddresses(partnerId: number): void {
    this.partnerService.listAddresses(partnerId).subscribe({
      next: (res) => this.addresses.set(res.data || []),
      error: () => this.addresses.set([]),
    });
  }

  openNewAddress(): void {
    this.editingAddress.set(null);
    this.addressForm.reset({ address_type: 'billing', is_default: false });
    this.addressDialogVisible.set(true);
  }

  editAddress(address: PartnerAddress): void {
    this.editingAddress.set(address);
    this.addressForm.patchValue({
      address_type: address.address_type,
      address_line_1: address.address_line_1,
      address_line_2: address.address_line_2,
      city: address.city,
      governorate: address.governorate,
      country_code: address.country_code,
      postal_code: address.postal_code,
      is_default: address.is_default,
    });
    this.addressDialogVisible.set(true);
  }

  saveAddress(): void {
    if (!this.addressForm.valid) { this.addressForm.markAllAsTouched(); return; }
    const partner = this.editingPartner();
    if (!partner) return;
    const data = this.addressForm.value;

    const obs = this.editingAddress()
      ? this.partnerService.updateAddress(this.editingAddress()!.id, data)
      : this.partnerService.createAddress(partner.id, data);

    obs.subscribe({
      next: () => {
        this.addressDialogVisible.set(false);
        this.loadAddresses(partner.id);
        this.messageService.add({ severity: 'success', summary: this.translate.instant('COMMON.SUCCESS'), detail: 'Address saved' });
      },
      error: (err) => this.messageService.add({ severity: 'error', summary: this.translate.instant('COMMON.ERROR'), detail: err.error?.message || 'Failed' }),
    });
  }

  deleteAddress(address: PartnerAddress): void {
    const partner = this.editingPartner();
    if (!partner) return;
    this.confirmationService.confirm({
      message: `Delete address "${address.address_line_1}"?`,
      accept: () => {
        this.partnerService.deleteAddress(address.id).subscribe({
          next: () => {
            this.loadAddresses(partner.id);
            this.messageService.add({ severity: 'success', summary: this.translate.instant('COMMON.SUCCESS'), detail: 'Address deleted' });
          },
          error: (err) => this.messageService.add({ severity: 'error', summary: this.translate.instant('COMMON.ERROR'), detail: err.error?.message || 'Failed' }),
        });
      },
    });
  }

  // Freeze / Unfreeze
  freezePartner(partner: Partner): void {
    this.confirmationService.confirm({
      message: this.translate.instant('PARTNERS.CONFIRM_FREEZE'),
      header: this.translate.instant('COMMON.CONFIRM'),
      accept: () => {
        this.partnerService.freeze(partner.id).subscribe({
          next: () => {
            const currentPage = Math.floor(this.first / this.rows) + 1;
            this.loadPage(currentPage);
            this.messageService.add({ severity: 'success', summary: this.translate.instant('COMMON.SUCCESS'), detail: this.translate.instant('PARTNERS.FREEZE_SUCCESS') });
          },
          error: (err) => this.messageService.add({ severity: 'error', summary: this.translate.instant('COMMON.ERROR'), detail: err.error?.message || 'Failed' }),
        });
      },
    });
  }

  unfreezePartner(partner: Partner): void {
    this.partnerService.unfreeze(partner.id).subscribe({
      next: () => {
        const currentPage = Math.floor(this.first / this.rows) + 1;
        this.loadPage(currentPage);
        this.messageService.add({ severity: 'success', summary: this.translate.instant('COMMON.SUCCESS'), detail: this.translate.instant('PARTNERS.UNFREEZE_SUCCESS') });
      },
      error: (err) => this.messageService.add({ severity: 'error', summary: this.translate.instant('COMMON.ERROR'), detail: err.error?.message || 'Failed' }),
    });
  }

  debtTypeOptions: any[] = [];
  roleFilterOptions: any[] = [];

  private initDebtForm(): void {
    this.debtForm = this.fb.group({
      business_partner_id: [null],
      amount: [0, [Validators.required, Validators.min(0.01)]],
      type: ['increase', Validators.required],
      reason: [''],
      reason_ar: [''],
      date: [new Date().toISOString().split('T')[0]],
      reference: [''],
    });
  }

  // Debt Changes
  openDebtChanges(partner: Partner): void {
    this.debtPartner.set(partner);
    this.loadDebtChanges(partner.id);
    this.debtForm.patchValue({
      business_partner_id: partner.id,
      amount: 0,
      type: 'increase',
      reason: '',
      reason_ar: '',
      date: new Date().toISOString().split('T')[0],
      reference: '',
    });
    this.debtForm.markAsUntouched();
    this.debtDialogVisible.set(true);
  }

  private loadDebtChanges(partnerId: number): void {
    this.partnerService.listDebtChanges(partnerId).subscribe({
      next: (res) => this.debtChanges.set(res.data || []),
      error: () => this.debtChanges.set([]),
    });
  }

  onCreateDebtChange(): void {
    if (!this.debtForm.valid) { this.debtForm.markAllAsTouched(); return; }
    const partner = this.debtPartner();
    if (!partner) return;
    this.savingPartner.set(true);
    this.partnerService.createDebtChange(this.debtForm.value).subscribe({
      next: () => {
        // Create journal entry for the debt change
        this.createDebtJournalEntry(partner, this.debtForm.value);
        this.loadDebtChanges(partner.id);
        this.debtForm.patchValue({ amount: 0, reason: '', reason_ar: '', reference: '' });
      },
      error: (err) => {
        this.savingPartner.set(false);
        this.messageService.add({ severity: 'error', summary: this.translate.instant('COMMON.ERROR'), detail: err.error?.message || 'Failed' });
      },
    });
  }

  private createDebtJournalEntry(partner: any, formVal: any): void {
    const amount = parseFloat(formVal.amount);
    const isIncrease = formVal.type === 'increase';
    const reason = formVal.reason || formVal.reason_ar || 'تغيير دين';
    // Retained earnings account id = 33
    const retainedEarningsId = 33;

    // Determine partner account
    let partnerAccountId: number | null = null;
    if (partner.is_customer && partner.ar_account_id) {
      partnerAccountId = partner.ar_account_id;
    } else if (partner.is_supplier && partner.ap_account_id) {
      partnerAccountId = partner.ap_account_id;
    }

    if (!partnerAccountId) {
      this.savingPartner.set(false);
      this.messageService.add({ severity: 'warn', summary: this.translate.instant('COMMON.WARNING'),
        detail: this.translate.instant('PARTNERS.NO_ACCOUNT_FOR_JE') });
      return;
    }

    // Build lines:
    // Customer increase: DR AR, CR Retained Earnings
    // Customer decrease: DR Retained Earnings, CR AR
    // Supplier increase: DR Retained Earnings, CR AP
    // Supplier decrease: DR AP, CR Retained Earnings
    let debitAccId: number, creditAccId: number;
    if (partner.is_customer) {
      debitAccId = isIncrease ? partnerAccountId : retainedEarningsId;
      creditAccId = isIncrease ? retainedEarningsId : partnerAccountId;
    } else {
      debitAccId = isIncrease ? retainedEarningsId : partnerAccountId;
      creditAccId = isIncrease ? partnerAccountId : retainedEarningsId;
    }

    const desc = `تغيير دين - ${partner.name} - ${isIncrease ? 'زيادة' : 'تخفيض'} ${amount}`;
    this.journalEntryService.create({
      date: formVal.date,
      description: desc,
      lines: [
        { account_id: debitAccId, debit: amount, credit: 0, description: reason },
        { account_id: creditAccId, debit: 0, credit: amount, description: reason },
      ],
    }).subscribe({
      next: () => {
        this.savingPartner.set(false);
        this.loadAccountBalances();
        this.messageService.add({ severity: 'success', summary: this.translate.instant('COMMON.SUCCESS'), detail: this.translate.instant('PARTNERS.DEBT_CHANGE_SUCCESS') });
      },
      error: () => {
        this.savingPartner.set(false);
        this.messageService.add({ severity: 'success', summary: this.translate.instant('COMMON.SUCCESS'), detail: this.translate.instant('PARTNERS.DEBT_CHANGE_SUCCESS') });
      },
    });
  }

  deletePartner(partner: Partner): void {
    this.confirmationService.confirm({
      message: `Are you sure you want to delete "${partner.name}"?`,
      header: 'Confirm Delete',
      icon: 'pi pi-exclamation-triangle',
      acceptButtonStyleClass: 'p-button-danger',
      accept: () => {
        this.partnerService.delete(partner.id).subscribe({
          next: () => {
            const currentPage = Math.floor(this.first / this.rows) + 1;
            this.loadPage(currentPage);
            this.messageService.add({ severity: 'success', summary: this.translate.instant('COMMON.SUCCESS'), detail: 'Deleted successfully' });
          },
          error: (err) => {
            this.messageService.add({ severity: 'error', summary: this.translate.instant('COMMON.ERROR'), detail: err.error?.message || 'Delete failed' });
          },
        });
      },
    });
  }

  onSave(): void {
    if (this.partnerForm.valid) {
      const formValue = this.partnerForm.value;
      const data = { ...formValue, name: formValue.name_ar };
      // Strip null optional foreign key fields to avoid API validation errors
      if (!data.partner_category_id) delete data.partner_category_id;
      if (!data.ar_account_id) delete data.ar_account_id;
      if (!data.ap_account_id) delete data.ap_account_id;
      const isEdit = !!this.editingPartner();
      const oldPartner = this.editingPartner();

      const obs = isEdit
        ? this.partnerService.update(this.editingPartner()!.id, data)
        : this.partnerService.create(data);

      this.savingPartner.set(true);
      obs.subscribe({
        next: (res) => {
          const savedPartner = res.data;
          if (isEdit) {
            // Check if role changed and account needs to be created
            this.ensurePartnerAccounts(savedPartner, oldPartner!, () => {
              this.savingPartner.set(false);
              this.dialogVisible.set(false);
              const currentPage = Math.floor(this.first / this.rows) + 1;
              this.loadPage(currentPage);
              this.store.dispatch(AccountsActions.loadAccounts({ force: true }));
              this.messageService.add({ severity: 'success', summary: this.translate.instant('COMMON.SUCCESS'), detail: 'Updated successfully' });
            });
          } else {
            this.savingPartner.set(false);
            this.dialogVisible.set(false);
            this.first = 0;
            this.activeTypeFilter = null;
            this.activeStatusFilter = null;
            this.activeClassFilter = null;
            this.activeRoleFilter = null;
            this.loadPage(1);
            this.store.dispatch(AccountsActions.loadAccounts({ force: true }));
            this.messageService.add({ severity: 'success', summary: this.translate.instant('COMMON.SUCCESS'), detail: 'Created successfully' });
          }
        },
        error: (err) => {
          this.savingPartner.set(false);
          this.messageService.add({ severity: 'error', summary: this.translate.instant('COMMON.ERROR'), detail: err.error?.message || 'Save failed' });
        },
      });
    } else {
      this.partnerForm.markAllAsTouched();
    }
  }

  /**
   * When editing a partner and role changes, auto-create missing AR/AP accounts
   * under the default parent account from settings.
   */
  private ensurePartnerAccounts(saved: Partner, old: Partner, done: () => void): void {
    // Create missing accounts whenever the role is active but account is null
    const needsAR = saved.is_customer && !saved.ar_account_id;
    const needsAP = saved.is_supplier && !saved.ap_account_id;

    if (!needsAR && !needsAP) { done(); return; }

    const tasks: { type: 'ar' | 'ap'; parentId: number | null }[] = [];
    if (needsAR) tasks.push({ type: 'ar', parentId: this.defaultClientParentId });
    if (needsAP) tasks.push({ type: 'ap', parentId: this.defaultSupplierParentId });

    let completed = 0;
    const updateData: any = {};

    for (const task of tasks) {
      if (!task.parentId) { completed++; if (completed === tasks.length) { this.finalizePartnerAccounts(saved.id, updateData, done); } continue; }

      this.accountService.getById(task.parentId).subscribe({
        next: (parentRes) => {
          const parent = parentRes.data;
          this.accountService.listAll().subscribe({
            next: (allRes) => {
              const siblings = allRes.data.filter(a => a.parent_id === parent.id);
              const maxSeq = siblings.reduce((max, s) => {
                const suffix = s.code.slice(parent.code.length);
                const num = parseInt(suffix, 10);
                return isNaN(num) ? max : Math.max(max, num);
              }, 0);
              const tryCreate = (seq: number, retries: number) => {
                const code = parent.code + String(seq).padStart(2, '0');
                this.accountService.create({
                  name: saved.name_ar || saved.name || '',
                  name_ar: saved.name_ar || saved.name || '',
                  name_en: saved.name_en || '',
                  code,
                  parent_id: parent.id,
                  classification: parent.classification,
                  nature: parent.nature || (task.type === 'ar' ? 'debit' : 'credit'),
                  account_type: 'detail',
                }).subscribe({
                  next: (accRes) => {
                    if (task.type === 'ar') updateData.ar_account_id = accRes.data.id;
                    else updateData.ap_account_id = accRes.data.id;
                    completed++;
                    if (completed === tasks.length) this.finalizePartnerAccounts(saved.id, updateData, done);
                  },
                  error: () => {
                    if (retries < 50) { tryCreate(seq + 1, retries + 1); }
                    else { completed++; if (completed === tasks.length) this.finalizePartnerAccounts(saved.id, updateData, done); }
                  },
                });
              };
              tryCreate(maxSeq + 1, 0);
            },
            error: () => { completed++; if (completed === tasks.length) this.finalizePartnerAccounts(saved.id, updateData, done); },
          });
        },
        error: () => { completed++; if (completed === tasks.length) this.finalizePartnerAccounts(saved.id, updateData, done); },
      });
    }
  }

  private finalizePartnerAccounts(partnerId: number, updateData: any, done: () => void): void {
    if (Object.keys(updateData).length === 0) { done(); return; }
    this.partnerService.update(partnerId, updateData).subscribe({
      next: () => done(),
      error: () => done(),
    });
  }

  retry(): void {
    this.first = 0;
    this.loadPage();
  }

  loadPage(page = 1, perPage = this.rows): void {
    this.tableLoading.set(true);
    this.partnerService.list(page, perPage).subscribe({
      next: (res) => {
        this.tableData.set(res.data);
        this.totalRecords.set(res.meta.total);
        this.tableLoading.set(false);
      },
      error: () => this.tableLoading.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);
  }

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

  getPartnerBalance(partner: any): number {
    // For customers: balance is on AR account (receivable = what they owe us)
    // For suppliers: balance is on AP account (payable = what we owe them)
    if (partner.is_customer && partner.ar_account_id) {
      return this.accountBalanceMap[partner.ar_account_id] ?? 0;
    }
    if (partner.is_supplier && partner.ap_account_id) {
      return this.accountBalanceMap[partner.ap_account_id] ?? 0;
    }
    return 0;
  }
}
