import { Component, inject, signal } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { Router } from '@angular/router';
import { Store } from '@ngrx/store';
import { TranslateModule, TranslateService } from '@ngx-translate/core';
import { ButtonModule } from 'primeng/button';
import { SelectModule } from 'primeng/select';
import { DatePickerModule } from 'primeng/datepicker';
import { TabsModule } from 'primeng/tabs';
import { TableModule } from 'primeng/table';
import { ToastModule } from 'primeng/toast';
import { ProgressSpinnerModule } from 'primeng/progressspinner';
import { TooltipModule } from 'primeng/tooltip';
import { MessageService } from 'primeng/api';
import { ReportService, BalanceSheetReport, IncomeStatementReport, CashFlowReport } from '../../core/services/report.service';
import { ExpenseRevenueService } from '../../core/services/expense-revenue.service';
import { selectAllPartners, PartnersActions, selectAllCostCenters, CostCentersActions, selectAllBudgets, BudgetsActions } from '../../core/store';

@Component({
  selector: 'app-reports',
  standalone: true,
  imports: [
    CommonModule, FormsModule, TranslateModule,
    ButtonModule, SelectModule, DatePickerModule, TabsModule,
    TableModule, ToastModule, ProgressSpinnerModule, TooltipModule,
  ],
  providers: [MessageService],
  templateUrl: './reports.component.html',
  styleUrl: './reports.component.scss',
})
export class ReportsComponent {
  private store = inject(Store);
  private reportService = inject(ReportService);
  private expRevService = inject(ExpenseRevenueService);
  private messageService = inject(MessageService);
  private translate = inject(TranslateService);
  private router = inject(Router);

  activeTab = signal(0);
  loading = signal(false);

  partners$ = this.store.select(selectAllPartners);
  costCenters$ = this.store.select(selectAllCostCenters);
  budgets$ = this.store.select(selectAllBudgets);

  // Balance Sheet
  bsDate = new Date();
  balanceSheet = signal<BalanceSheetReport | null>(null);

  // Income Statement
  isStartDate = new Date(new Date().getFullYear(), 0, 1);
  isEndDate = new Date();
  incomeStatement = signal<IncomeStatementReport | null>(null);

  // Cash Flow
  cfStartDate = new Date(new Date().getFullYear(), 0, 1);
  cfEndDate = new Date();
  cashFlow = signal<CashFlowReport | null>(null);

  // Aging
  agingDate = new Date();
  agingType: string = 'receivable';
  agingTypeOptions = [
    { label: this.translate.instant('COMMON.RECEIVABLE'), value: 'receivable' },
    { label: this.translate.instant('COMMON.PAYABLE'), value: 'payable' },
  ];
  agingData = signal<any>(null);
  loadingAging = signal(false);

  // Partner Statement
  psPartnerId: number | null = null;
  psStartDate = new Date(new Date().getFullYear(), 0, 1);
  psEndDate = new Date();
  partnerStatement = signal<any>(null);
  loadingPS = signal(false);

  // Cost Center Report
  ccCostCenterId: number | null = null;
  ccStartDate = new Date(new Date().getFullYear(), 0, 1);
  ccEndDate = new Date();
  costCenterReport = signal<any>(null);
  loadingCC = signal(false);

  // Budget vs Actual
  bvaBudgetId: number | null = null;
  budgetVsActual = signal<any>(null);
  loadingBVA = signal(false);

  // Expense Report
  expStartDate = new Date(new Date().getFullYear(), 0, 1);
  expEndDate = new Date();
  expenseReport = signal<any>(null);
  loadingExp = signal(false);

  // Revenue Report
  revStartDate = new Date(new Date().getFullYear(), 0, 1);
  revEndDate = new Date();
  revenueReport = signal<any>(null);
  loadingRev = signal(false);

  // Profit Analysis
  profitStartDate = new Date(new Date().getFullYear(), 0, 1);
  profitEndDate = new Date();
  profitAnalysis = signal<any>(null);
  loadingProfit = signal(false);

  // Tax Reports
  taxStartDate = new Date(new Date().getFullYear(), 0, 1);
  taxEndDate = new Date();
  taxSummary = signal<any>(null);
  taxDetails = signal<any>(null);
  loadingTax = signal(false);
  taxView: 'summary' | 'details' = 'summary';

  // Voucher Reports
  vrStartDate = new Date(new Date().getFullYear(), 0, 1);
  vrEndDate = new Date();
  vrType: 'receipts' | 'payments' | 'cash-flow' = 'receipts';
  voucherReport = signal<any>(null);
  loadingVR = signal(false);

  constructor() {
    this.store.dispatch(PartnersActions.loadPartners({}));
    this.store.dispatch(CostCentersActions.loadCostCenters({}));
    this.store.dispatch(BudgetsActions.loadBudgets({}));
  }

  loadBalanceSheet(): void {
    this.loading.set(true);
    this.reportService.getBalanceSheet(this.formatDate(this.bsDate)).subscribe({
      next: (res) => { this.balanceSheet.set(res.data); this.loading.set(false); },
      error: (err) => { this.loading.set(false); this.showError(err); },
    });
  }

  loadIncomeStatement(): void {
    this.loading.set(true);
    this.reportService.getIncomeStatement(this.formatDate(this.isStartDate), this.formatDate(this.isEndDate)).subscribe({
      next: (res) => { this.incomeStatement.set(res.data); this.loading.set(false); },
      error: (err) => { this.loading.set(false); this.showError(err); },
    });
  }

  loadCashFlow(): void {
    this.loading.set(true);
    this.reportService.getCashFlow(this.formatDate(this.cfStartDate), this.formatDate(this.cfEndDate)).subscribe({
      next: (res) => { this.cashFlow.set(res.data); this.loading.set(false); },
      error: (err) => { this.loading.set(false); this.showError(err); },
    });
  }

  loadAging(): void {
    this.loadingAging.set(true);
    this.reportService.getAging(this.formatDate(this.agingDate), this.agingType).subscribe({
      next: (res) => { this.agingData.set(res.data); this.loadingAging.set(false); },
      error: (err) => { this.loadingAging.set(false); this.showError(err); },
    });
  }

  loadPartnerStatement(): void {
    if (!this.psPartnerId) return;
    this.loadingPS.set(true);
    this.reportService.getPartnerStatement(this.psPartnerId, this.formatDate(this.psStartDate), this.formatDate(this.psEndDate)).subscribe({
      next: (res) => { this.partnerStatement.set(res.data); this.loadingPS.set(false); },
      error: (err) => { this.loadingPS.set(false); this.showError(err); },
    });
  }

  loadCostCenterReport(): void {
    if (!this.ccCostCenterId) return;
    this.loadingCC.set(true);
    this.reportService.getCostCenterReport(this.ccCostCenterId, this.formatDate(this.ccStartDate), this.formatDate(this.ccEndDate)).subscribe({
      next: (res) => { this.costCenterReport.set(res.data); this.loadingCC.set(false); },
      error: (err) => { this.loadingCC.set(false); this.showError(err); },
    });
  }

  loadBudgetVsActual(): void {
    if (!this.bvaBudgetId) return;
    this.loadingBVA.set(true);
    this.reportService.getBudgetVsActual(this.bvaBudgetId).subscribe({
      next: (res) => { this.budgetVsActual.set(res.data); this.loadingBVA.set(false); },
      error: (err) => { this.loadingBVA.set(false); this.showError(err); },
    });
  }

  loadExpenseReport(): void {
    this.loadingExp.set(true);
    this.expRevService.expenseReport(this.formatDate(this.expStartDate), this.formatDate(this.expEndDate)).subscribe({
      next: (res) => { this.expenseReport.set(res.data); this.loadingExp.set(false); },
      error: (err) => { this.loadingExp.set(false); this.showError(err); },
    });
  }

  loadRevenueReport(): void {
    this.loadingRev.set(true);
    this.expRevService.revenueReport(this.formatDate(this.revStartDate), this.formatDate(this.revEndDate)).subscribe({
      next: (res) => { this.revenueReport.set(res.data); this.loadingRev.set(false); },
      error: (err) => { this.loadingRev.set(false); this.showError(err); },
    });
  }

  loadProfitAnalysis(): void {
    this.loadingProfit.set(true);
    this.expRevService.profitAnalysis(this.formatDate(this.profitStartDate), this.formatDate(this.profitEndDate)).subscribe({
      next: (res) => { this.profitAnalysis.set(res.data); this.loadingProfit.set(false); },
      error: (err) => { this.loadingProfit.set(false); this.showError(err); },
    });
  }

  loadTaxReport(): void {
    this.loadingTax.set(true);
    const start = this.formatDate(this.taxStartDate);
    const end = this.formatDate(this.taxEndDate);
    if (this.taxView === 'summary') {
      this.expRevService.taxSummary(start, end).subscribe({
        next: (res) => { this.taxSummary.set(res.data); this.loadingTax.set(false); },
        error: (err) => { this.loadingTax.set(false); this.showError(err); },
      });
    } else {
      this.expRevService.taxDetails(start, end).subscribe({
        next: (res: any) => {
          // API returns { data: [...], meta: {...} } — data is the array directly
          const items = Array.isArray(res.data) ? res.data : (res.data?.items || res.data?.entries || []);
          this.taxDetails.set(items);
          this.loadingTax.set(false);
        },
        error: (err) => { this.loadingTax.set(false); this.showError(err); },
      });
    }
  }

  loadVoucherReport(): void {
    this.loadingVR.set(true);
    const start = this.formatDate(this.vrStartDate);
    const end = this.formatDate(this.vrEndDate);
    const obs = this.vrType === 'receipts' ? this.reportService.getReceiptVoucherReport(start, end)
      : this.vrType === 'payments' ? this.reportService.getPaymentVoucherReport(start, end)
      : this.reportService.getVoucherCashFlow(start, end);
    obs.subscribe({
      next: (res) => { this.voucherReport.set(res.data); this.loadingVR.set(false); },
      error: (err) => { this.loadingVR.set(false); this.showError(err); },
    });
  }

  onTabChange(index: string | number | undefined): void {
    this.activeTab.set(Number(index) || 0);
  }

  retry(): void {
    // Reports are query-driven; refresh lookups
    this.store.dispatch(PartnersActions.loadPartners({ forceReload: true }));
    this.store.dispatch(CostCentersActions.loadCostCenters({ forceReload: true }));
    this.store.dispatch(BudgetsActions.loadBudgets({ forceReload: true }));
  }

  private showError(err: any): void {
    this.messageService.add({ severity: 'error', summary: this.translate.instant('COMMON.ERROR'), detail: err.error?.message || 'Failed' });
  }

  goToJournalEntries(): void {
    this.router.navigate(['/accounting/journal-entries']);
  }

  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}`;
  }
}
