import { Component, OnInit } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { ChartsModule, SeriesClickEvent } from '@progress/kendo-angular-charts';
import { DateInputsModule } from '@progress/kendo-angular-dateinputs';
import { GridModule, PageChangeEvent } from '@progress/kendo-angular-grid';
import { ButtonsModule } from '@progress/kendo-angular-buttons';
import { DateUtils } from '../../../../shared/utilities/date-utils';
import { ExpenseApiService } from '../../../expense/services/expense-api.service';
import { ExpenseListItemDto } from '../../../expense/models/expense.model';
import { FinanceDashboardApiService } from '../../services/finance-dashboard-api.service';
import { FinanceSummaryDto, PieSlice, DrillLevel, Crumb } from '../../models/finance-dashboard.model';
import { PageHeaderActionsDirective } from '../../../../shared/directives/page-header-actions.directive';

// Expense scope for the dashboard: Paid + Approved (shared by the pies and the detail grid).
const DASHBOARD_STATUSES = 'Paid,Approved';
type QuickRange = 'month' | 'lastMonth' | 'year' | null;

@Component({
  selector: 'app-finance-dashboard-page',
  standalone: true,
  imports: [CommonModule, FormsModule, ChartsModule, DateInputsModule, GridModule, ButtonsModule, PageHeaderActionsDirective],
  templateUrl: './finance-dashboard-page.component.html',
  styleUrls: ['./finance-dashboard-page.component.scss'],
})
export class FinanceDashboardPageComponent implements OnInit {
  // All-time balance card (independent of the date range).
  summary?: FinanceSummaryDto;

  // Date range driving the charts + detail table (defaults to the current month).
  from: Date = DateUtils.getFirstDayOfCurrentMonth();
  to: Date = DateUtils.getLastDayOfCurrentMonth();
  activeRange: QuickRange = 'month';

  // Charts.
  incomeExpense: PieSlice[] = [];
  breakdown: PieSlice[] = [];

  // Curated colour palettes (harmonised with the app's blue/teal brand).
  readonly incomeExpenseColors = ['#0c8d42', '#d8443c'];
  readonly palette = ['#0279cf', '#16b3c9', '#15588e', '#5b8def', '#7f76a9', '#d6ad1c', '#2fa37a', '#c35573'];

  // Drill state: Ministry -> Category Group -> Sub-Category.
  level: DrillLevel = 'ministry';
  selectedMinistryId: number | null = null;
  selectedGroupId: number | null = null;
  selectedSubId: number | null = null;
  breadcrumb: Crumb[] = [{ level: 'ministry', id: null, label: 'All / 全部' }];

  // Detail grid.
  detailRows: ExpenseListItemDto[] = [];
  detailTotal = 0;
  detailPage = 1;
  detailPageSize = 8;
  detailLoading = false;

  constructor(
    private api: FinanceDashboardApiService,
    private expenseApi: ExpenseApiService,
  ) {}

  ngOnInit(): void {
    this.api.getSummary().subscribe(s => (this.summary = s));
    this.reloadRange();
  }

  // Local Y/M/D — never toISOString() (it shifts the day across timezones).
  private fmt(d: Date): string { return DateUtils.format(d, 'yyyy-MM-dd'); }

  /** Date range changed: refresh income/expense and reset the drill to the top. */
  reloadRange(): void {
    if (!this.from || !this.to) return;
    const from = this.fmt(this.from), to = this.fmt(this.to);
    this.api.getIncomeExpense(from, to).subscribe(r => {
      this.incomeExpense = [
        { id: 1, label: 'Income / 收入', amount: r.income },
        { id: 2, label: 'Expense / 支出', amount: r.expense },
      ];
    });
    this.resetDrill();
    this.loadBreakdown();
    this.loadDetail();
  }

  /** Quick range chips. */
  setQuickRange(range: Exclude<QuickRange, null>): void {
    const now = new Date();
    if (range === 'month') {
      this.from = new Date(now.getFullYear(), now.getMonth(), 1);
      this.to = new Date(now.getFullYear(), now.getMonth() + 1, 0);
    } else if (range === 'lastMonth') {
      this.from = new Date(now.getFullYear(), now.getMonth() - 1, 1);
      this.to = new Date(now.getFullYear(), now.getMonth(), 0);
    } else {
      this.from = new Date(now.getFullYear(), 0, 1);
      this.to = new Date(now.getFullYear(), 11, 31);
    }
    this.activeRange = range;
    this.reloadRange();
  }

  onManualDateChange(): void {
    this.activeRange = null;
    this.reloadRange();
  }

  private resetDrill(): void {
    this.level = 'ministry';
    this.selectedMinistryId = null;
    this.selectedGroupId = null;
    this.selectedSubId = null;
    this.breadcrumb = [{ level: 'ministry', id: null, label: 'All / 全部' }];
  }

  private loadBreakdown(): void {
    this.api.getBreakdown(this.fmt(this.from), this.fmt(this.to), this.selectedMinistryId, this.selectedGroupId)
      .subscribe(slices => (this.breakdown = slices));
  }

  private loadDetail(): void {
    this.detailLoading = true;
    this.expenseApi.getPaged({
      statuses: DASHBOARD_STATUSES,
      from: this.fmt(this.from), to: this.fmt(this.to),
      ministryId: this.selectedMinistryId ?? undefined,
      categoryGroupId: this.selectedGroupId ?? undefined,
      subCategoryId: this.selectedSubId ?? undefined,
      page: this.detailPage, pageSize: this.detailPageSize,
    }).subscribe({
      next: r => { this.detailRows = r.items; this.detailTotal = r.totalCount; this.detailLoading = false; },
      error: () => { this.detailLoading = false; },
    });
  }

  onSliceClick(e: SeriesClickEvent): void { this.drillInto(e.dataItem as PieSlice); }

  /** Drill deeper into a slice (from a chart click or a legend row click). */
  drillInto(slice: PieSlice): void {
    if (this.level === 'ministry') {
      this.selectedMinistryId = slice.id;
      this.level = 'group';
      this.breadcrumb.push({ level: 'group', id: slice.id, label: slice.label });
    } else if (this.level === 'group') {
      this.selectedGroupId = slice.id;
      this.level = 'subcategory';
      this.breadcrumb.push({ level: 'subcategory', id: slice.id, label: slice.label });
    } else {
      // Leaf: filter the detail table only; no further drill.
      this.selectedSubId = this.selectedSubId === slice.id ? null : slice.id;
      this.detailPage = 1;
      this.loadDetail();
      return;
    }
    this.detailPage = 1;
    this.loadBreakdown();
    this.loadDetail();
  }

  /** Step back up via the breadcrumb. */
  goToCrumb(i: number): void {
    this.breadcrumb = this.breadcrumb.slice(0, i + 1);
    const last = this.breadcrumb[this.breadcrumb.length - 1];
    this.selectedSubId = null;
    if (last.level === 'ministry') {
      this.selectedMinistryId = null;
      this.selectedGroupId = null;
      this.level = 'ministry';
    } else if (last.level === 'group') {
      this.selectedGroupId = null;
      this.level = 'group';
    }
    this.detailPage = 1;
    this.loadBreakdown();
    this.loadDetail();
  }

  onDetailPageChange(e: PageChangeEvent): void {
    this.detailPage = Math.floor(e.skip / this.detailPageSize) + 1;
    this.loadDetail();
  }

  get detailSkip(): number { return (this.detailPage - 1) * this.detailPageSize; }

  // --- Derived figures for the donut centres + custom legends ---
  get rangeIncome(): number { return this.incomeExpense[0]?.amount ?? 0; }
  get rangeExpense(): number { return this.incomeExpense[1]?.amount ?? 0; }
  get rangeNet(): number { return this.rangeIncome - this.rangeExpense; }
  get breakdownTotal(): number { return this.breakdown.reduce((s, x) => s + x.amount, 0); }
  get currentLevelLabel(): string { return this.breadcrumb[this.breadcrumb.length - 1]?.label ?? ''; }

  /** The drill hint shown under the breakdown donut. */
  get drillHint(): string {
    if (this.level === 'ministry') return 'Click a ministry to drill in / 點選 Ministry 深入';
    if (this.level === 'group') return 'Click a category group / 點選 Category Group';
    return 'Click a sub-category to filter the table / 點選明細';
  }

  percent(amount: number, total: number): number {
    return total > 0 ? (amount / total) * 100 : 0;
  }

  statusClass(status: string): string {
    return ({ Paid: 'is-paid', Approved: 'is-approved' } as Record<string, string>)[status] ?? '';
  }
}
