import { ChangeDetectorRef, Component, OnInit } from '@angular/core';
import { CommonModule, DatePipe } from '@angular/common';
import { HttpClient } from '@angular/common/http';
import { Router } from '@angular/router';
import { Observable, forkJoin } from 'rxjs'; // Import Observable, forkJoin
import { finalize, catchError, map } from 'rxjs/operators'; // Import operators
import { of } from 'rxjs'; // Import 'of' to create an Observable from a value

// NG-ZORRO 组件
import { NzCardModule } from 'ng-zorro-antd/card';
import { NzGridModule } from 'ng-zorro-antd/grid';
import { NzStatisticModule } from 'ng-zorro-antd/statistic';
import { NzTableModule } from 'ng-zorro-antd/table';
import { NzTabsModule } from 'ng-zorro-antd/tabs';
import { NzTagModule } from 'ng-zorro-antd/tag';
import { NzSpinModule } from 'ng-zorro-antd/spin';
import { NzMessageService } from 'ng-zorro-antd/message';
import { NzDividerModule } from 'ng-zorro-antd/divider';
import { NzDatePickerModule } from 'ng-zorro-antd/date-picker';
import { FormsModule } from '@angular/forms';
import { NzSelectModule } from 'ng-zorro-antd/select';
import { NzButtonModule } from 'ng-zorro-antd/button';
import { NzIconModule } from 'ng-zorro-antd/icon';
import { NzEmptyModule } from 'ng-zorro-antd/empty';
import { NzToolTipModule } from 'ng-zorro-antd/tooltip';
import { NzProgressModule } from 'ng-zorro-antd/progress';
import { NzDescriptionsModule } from 'ng-zorro-antd/descriptions';

// Chart.js
import { BaseChartDirective } from 'ng2-charts';
import {
  Chart,
  ChartConfiguration,
  ChartOptions,
  registerables,
} from 'chart.js';

@Component({
  selector: 'app-message-dashboard',
  standalone: true,
  imports: [
    CommonModule,
    NzCardModule,
    NzGridModule,
    NzStatisticModule,
    NzTableModule,
    NzTabsModule,
    NzTagModule,
    NzSpinModule,
    NzDividerModule,
    NzDatePickerModule,
    FormsModule,
    NzSelectModule,
    NzButtonModule,
    NzIconModule,
    NzEmptyModule,
    NzToolTipModule,
    NzProgressModule,
    NzDescriptionsModule,
    DatePipe,
    BaseChartDirective,
  ],
  templateUrl: './message-dashboard.component.html',
  styleUrls: ['./message-dashboard.component.css'],
})
export class MessageDashboardComponent implements OnInit {
  isLoading = false;
  overallStats: any = null;
  strategyStats: any[] = [];
  templateStats: any[] = [];
  dailyTrends: any[] = [];
  avgDeliveryTime: any = null;
  activeTab: number = 0;

  // 日期范围
  dateRange: Date[] = [];

  // 组合图表配置
  public combinedChartData: ChartConfiguration<'bar'>['data'] = {
    labels: [],
    datasets: [
      {
        label: '总发送量',
        data: [],
        backgroundColor: '#1890ff',
        yAxisID: 'y',
      },
      {
        label: '成功发送',
        data: [],
        backgroundColor: '#52c41a',
        yAxisID: 'y',
      },
      {
        label: '已送达',
        data: [],
        backgroundColor: '#13c2c2',
        yAxisID: 'y',
      },
      {
        label: '展示数',
        data: [],
        backgroundColor: '#faad14',
        yAxisID: 'y',
      },
      {
        label: '点击数',
        data: [],
        backgroundColor: '#722ed1',
        yAxisID: 'y',
      },
      {
        label: '失败数',
        data: [],
        backgroundColor: '#f5222d',
        yAxisID: 'y',
      },
    ],
  };

  public rateChartData: ChartConfiguration<'line'>['data'] = {
    labels: [],
    datasets: [
      {
        label: '发送成功率',
        data: [],
        borderColor: '#1890ff',
        backgroundColor: 'rgba(24, 144, 255, 0.1)',
        yAxisID: 'y1',
        tension: 0.3,
        fill: true,
      },
      {
        label: '送达率',
        data: [],
        borderColor: '#52c41a',
        backgroundColor: 'rgba(82, 196, 26, 0.1)',
        yAxisID: 'y1',
        tension: 0.3,
        fill: true,
      },
      {
        label: '展示率',
        data: [],
        borderColor: '#faad14',
        backgroundColor: 'rgba(250, 173, 20, 0.1)',
        yAxisID: 'y1',
        tension: 0.3,
        fill: true,
      },
      {
        label: '点击率',
        data: [],
        borderColor: '#722ed1',
        backgroundColor: 'rgba(114, 46, 209, 0.1)',
        yAxisID: 'y1',
        tension: 0.3,
        fill: true,
      },
    ],
  };

  public combinedChartOptions: ChartOptions<'bar' | 'line'> = {
    responsive: true,
    maintainAspectRatio: false,
    plugins: {
      tooltip: {
        mode: 'index',
        intersect: false,
      },
      legend: {
        position: 'top',
      },
    },
    scales: {
      y: {
        type: 'linear',
        display: true,
        position: 'left',
        title: {
          display: true,
          text: '消息数量',
        },
        beginAtZero: true,
      },
      y1: {
        type: 'linear',
        display: true,
        position: 'right',
        title: {
          display: true,
          text: '百分比(%)',
        },
        min: 0,
        max: 100,
        grid: {
          drawOnChartArea: false,
        },
      },
    },
  };

  constructor(
    private http: HttpClient,
    private message: NzMessageService,
    private router: Router,
    private cd: ChangeDetectorRef // 注入 ChangeDetectorRef
  ) {
    Chart.register(...registerables);
  }

  ngOnInit(): void {
    this.loadAllStatistics();
  }

  loadAllStatistics(): void {
    this.isLoading = true;

    // Use forkJoin to run all requests in parallel and wait for all to complete
    forkJoin({
      overall: this.http
        .get(`/api/message/statistics/overall?t=${new Date()}`)
        .pipe(
          map((res: any) => res?.data || null),
          catchError((err) => {
            console.error('Failed to load overall statistics:', err);
            this.message.error('加载整体统计失败');
            return of(null); // Return a default value to prevent forkJoin from failing
          })
        ),
      strategies: this.http
        .get(`/api/message/statistics/by-strategy?t=${new Date()}`)
        .pipe(
          map((res: any) => res?.data || []),
          catchError((err) => {
            console.error('Failed to load strategy statistics:', err);
            this.message.error('加载策略统计失败');
            return of([]);
          })
        ),
      templates: this.http
        .get(`/api/message/statistics/by-template?t=${new Date()}`)
        .pipe(
          map((res: any) => res?.data || []),
          catchError((err) => {
            console.error('Failed to load template statistics:', err);
            this.message.error('加载模板统计失败');
            return of([]);
          })
        ),
      dailyTrends: this.http
        .get(`/api/message/statistics/daily-trends?t=${new Date()}`)
        .pipe(
          map((res: any) => res?.data || []),
          catchError((err) => {
            console.error('Failed to load daily trends:', err);
            this.message.error('加载每日趋势失败');
            return of([]);
          })
        ),
      // avgTime: this.http
      //   .get('/api/message/statistics/avg-delivery-time')
      //   .pipe(
      //     map((res: any) => res?.data || null),
      //     catchError((err) => {
      //       console.error('Failed to load average delivery time:', err);
      //       this.message.error('加载平均送达时间失败');
      //       return of(null);
      //     })
      //   ),
    })
      .pipe(
        finalize(() => {
          this.isLoading = false;
          // 在所有数据都赋值完毕后，手动触发变更检测
          this.cd.detectChanges();
        })
      )
      .subscribe((results: any) => {
        // Assign data to component properties
        this.overallStats = results.overall;
        this.strategyStats = results.strategies;
        this.templateStats = results.templates;
        this.dailyTrends = results.dailyTrends;
        // this.avgDeliveryTime = results.avgTime;

        // Update charts based on the latest data
        this.updateChartData();
      });
  }

  private updateChartData(): void {
    // 更新组合图表数据
    this.combinedChartData = {
      labels: this.dailyTrends.map((t) => this.formatDate(t.date)),
      datasets: [
        {
          ...this.combinedChartData.datasets[0],
          data: this.dailyTrends.map((t) => t.totalRecords || 0),
        },
        {
          ...this.combinedChartData.datasets[1],
          data: this.dailyTrends.map((t) => t.sent || 0),
        },
        {
          ...this.combinedChartData.datasets[2],
          data: this.dailyTrends.map((t) => t.delivered || 0),
        },
        {
          ...this.combinedChartData.datasets[3],
          data: this.dailyTrends.map((t) => t.displayCount || 0),
        },
        {
          ...this.combinedChartData.datasets[4],
          data: this.dailyTrends.map((t) => t.opened || 0),
        },
        {
          ...this.combinedChartData.datasets[5],
          data: this.dailyTrends.map((t) => t.failed || 0),
        },
      ],
    };

    // 更新比率图表数据
    this.rateChartData = {
      labels: this.dailyTrends.map((t) => this.formatDate(t.date)),
      datasets: [
        {
          ...this.rateChartData.datasets[0],
          data: this.dailyTrends.map((t) => (t.sentSuccessRate || 0) * 100),
        },
        {
          ...this.rateChartData.datasets[1],
          data: this.dailyTrends.map((t) => (t.deliveredRate || 0) * 100),
        },
        {
          ...this.rateChartData.datasets[2],
          data: this.dailyTrends.map((t) => (t.displayRate || 0) * 100),
        },
        {
          ...this.rateChartData.datasets[3],
          data: this.dailyTrends.map((t) => (t.clickThroughRate || 0) * 100),
        },
      ],
    };
  }

  refreshData(): void {
    this.loadAllStatistics();
  }

  navigateToStrategy(strategyName: string): void {
    this.router.navigate(['/message-strategy'], {
      queryParams: { strategyName: strategyName },
    });
  }

  navigateToTemplate(templateName: string): void {
    this.router.navigate(['/message-template'], {
      queryParams: { templateName: templateName },
    });
  }

  formatPercentage(value: number): string {
    return (value * 100).toFixed(2) + '%';
  }

  formatPercentageToNumber(value: number): number {
    return Number((value * 100).toFixed(2));
  }

  formatSeconds(seconds: number): string {
    if (seconds < 60) {
      return seconds.toFixed(2) + '秒';
    } else {
      return (seconds / 60).toFixed(2) + '分钟';
    }
  }

  preciseRound(num: number, decimalPlaces: number): number {
    if (decimalPlaces === 0) return Math.round(num);
    const multiplier = Math.pow(10, decimalPlaces);
    return Number(Math.round(num * multiplier) / multiplier);
  }

  private formatDate(date: string | null): string {
    if (!date) return '未知日期';
    return new Date(date).toLocaleDateString();
  }
}
