import { ChangeDetectorRef, Component, OnInit } from '@angular/core';
import { CommonModule, DatePipe } from '@angular/common';
import { HttpClient, HttpParams } from '@angular/common/http';
import { FormsModule } from '@angular/forms';
import { Observable, of } from 'rxjs';
import { catchError, finalize, map } from 'rxjs/operators';

// 国家代码转换库
import * as countries from 'i18n-iso-countries';
import * as countriesZh from 'i18n-iso-countries/langs/zh.json';
import * as countriesEn from 'i18n-iso-countries/langs/en.json';

// 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 { 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 { NzFormModule } from 'ng-zorro-antd/form';
import { NzInputModule } from 'ng-zorro-antd/input';
import { NzProgressModule } from 'ng-zorro-antd/progress';
import { NzCheckboxModule } from 'ng-zorro-antd/checkbox';

// Chart.js
import { BaseChartDirective } from 'ng2-charts';
import {
  Chart,
  ChartConfiguration,
  ChartOptions,
  registerables,
} from 'chart.js';
import { NzTooltipModule } from 'ng-zorro-antd/tooltip';
import { NzPageHeaderModule } from 'ng-zorro-antd/page-header';
import { NzImageModule } from 'ng-zorro-antd/image';

// 注册语言包
countries.registerLocale(countriesZh as any);
countries.registerLocale(countriesEn as any);

// 多维统计数据接口定义
interface MultiDimensionalStats {
  date: string;
  templateName?: string;
  strategyName?: string;
  cc?: string;
  image?: string;
  totalRecords: number;
  sent: number;
  delivered: number;
  opened: number;
  failed: number;
  displayCount: number;
  sentSuccessRate: number;
  deliveredRate: number;
  displayRate: number;
  clickThroughRate: number;
  tokenInvalidationRate: number;
}

// 筛选条件接口
interface Filters {
  startDate?: Date;
  endDate?: Date;
  templateName?: string;
  strategyName?: string;
  cc?: string;
  image?: string;
}

// 维度选项
interface DimensionOption {
  label: string;
  value: string;
  checked: boolean;
}

@Component({
  selector: 'app-multi-dimensional-dashboard',
  standalone: true,
  imports: [
    CommonModule,
    FormsModule,
    NzCardModule,
    NzGridModule,
    NzStatisticModule,
    NzTableModule,
    NzTabsModule,
    NzTagModule,
    NzSpinModule,
    NzDividerModule,
    NzDatePickerModule,
    NzSelectModule,
    NzButtonModule,
    NzIconModule,
    NzEmptyModule,
    NzFormModule,
    NzInputModule,
    NzProgressModule,
    NzCheckboxModule,
    NzTooltipModule,
    NzPageHeaderModule,
    NzImageModule,
    DatePipe,
    BaseChartDirective,
  ],
  templateUrl: './multi-dimensional-dashboard.component.html',
  styleUrls: ['./multi-dimensional-dashboard.component.css'],
})
export class MultiDimensionalDashboardComponent implements OnInit {
  // 加载状态
  isLoading = false;

  // 统计数据
  statsData: MultiDimensionalStats[] = [];
  filteredStats: MultiDimensionalStats[] = [];
  summaryStats: any = null;

  // 筛选条件
  filters: Filters = {};
  dateRange: Date[] = [];

  // 可选维度和选中的维度
  dimensionOptions: DimensionOption[] = [
    { label: '模板', value: 'templateName', checked: true },
    { label: '策略', value: 'strategyName', checked: true },
    { label: '国家', value: 'cc', checked: true },
    { label: '图片', value: 'image', checked: true },
  ];

  isDimensionOptionExists(name: string): boolean {
    return this.dimensionOptions.some((d) => d.value === name && d.checked);
  }

  // 图表配置
  public chartData: ChartConfiguration<'bar' | 'line'>['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' },
      {
        label: '送达率',
        data: [],
        borderColor: '#13c2c2',
        backgroundColor: 'transparent',
        yAxisID: 'y1',
        type: 'line',
        tension: 0.3,
      },
      {
        label: '点击率',
        data: [],
        borderColor: '#722ed1',
        backgroundColor: 'transparent',
        yAxisID: 'y1',
        type: 'line',
        tension: 0.3,
      },
    ],
  };

  public chartOptions: 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: 1,
        grid: { drawOnChartArea: false },
        ticks: {
          callback: (value) => ((value as number) * 100).toFixed(0) + '%',
        },
      },
    },
  };

  // 表格排序
  sortField: string | null = 'date';
  sortDirection: 'ascend' | 'descend' = 'ascend';

  // 可用的筛选选项（从数据中提取）
  availableTemplates: string[] = [];
  availableStrategies: string[] = [];
  availableCountries: string[] = [];
  availableImages: string[] = [];

  getImageId(imageUrl: string): string | null {
    if (!imageUrl) return null;

    // 更健壮的正则表达式，允许640后有或没有斜杠
    const regex = /640\/?([a-f0-9]+)\.png/i;
    const match = imageUrl.match(regex);

    return match ? match[1] : null;
  }

  constructor(
    private http: HttpClient,
    private message: NzMessageService,
    private cd: ChangeDetectorRef
  ) {
    Chart.register(...registerables);
  }

  ngOnInit(): void {
    // 默认加载最近7天数据
    const endDate = new Date();
    const startDate = new Date();
    startDate.setDate(startDate.getDate() - 7);
    this.dateRange = [startDate, endDate];
    this.filters.startDate = startDate;
    this.filters.endDate = endDate;

    this.loadStatistics();
  }

  /**
   * 加载多维统计数据
   */
  loadStatistics(): void {
    if (!this.isDateRangeValid()) {
      return;
    }

    this.isLoading = true;

    // 构建查询参数
    let params = new HttpParams();
    if (this.filters.startDate) {
      params = params.set(
        'startDate',
        this.formatDateForApi(this.filters.startDate)
      );
    }
    if (this.filters.endDate) {
      params = params.set(
        'endDate',
        this.formatDateForApi(this.filters.endDate)
      );
    }
    if (this.filters.templateName) {
      params = params.set('templateName', this.filters.templateName);
    }
    if (this.filters.strategyName) {
      params = params.set('strategyName', this.filters.strategyName);
    }
    if (this.filters.cc) {
      params = params.set('cc', this.filters.cc);
    }
    if (this.filters.image) {
      params = params.set('image', this.filters.image);
    }

    this.http
      .get('/api/message/statistics/multi-dimensional', { params })
      .pipe(
        map((res: any) => res?.data || []),
        catchError((err) => {
          console.error('获取多维统计数据失败:', err);
          this.message.error('获取统计数据失败，请重试');
          return of([]);
        }),
        finalize(() => {
          this.isLoading = false;
          this.cd.detectChanges();
        })
      )
      .subscribe((data: MultiDimensionalStats[]) => {
        this.statsData = data;
        this.processData();
      });
  }

  /**
   * 处理数据 - 提取筛选选项、计算汇总、更新图表
   */
  processData(): void {
    // 过滤数据基于选中的维度
    this.filteredStats = this.getFilteredDataByDimensions();

    // 提取可用的筛选选项
    this.extractAvailableOptions();

    // 计算汇总统计
    this.calculateSummaryStats();

    // 更新图表数据
    this.updateChartData();
  }

  /**
   * 根据选中的维度过滤数据
   */
  getFilteredDataByDimensions(): MultiDimensionalStats[] {
    const checkedDimensions = this.dimensionOptions
      .filter((option) => option.checked)
      .map((option) => option.value);

    // 如果没有选中任何维度，返回空
    if (checkedDimensions.length === 0) {
      return [];
    }

    // 按选中的维度对数据进行分组汇总
    const groupedData: { [key: string]: MultiDimensionalStats } = {};

    this.statsData.forEach((item) => {
      // 创建分组键 - 基于选中的维度
      const groupKeyParts: string[] = [];
      checkedDimensions.forEach((dim) => {
        groupKeyParts.push(`${dim}=${(item as any)[dim] || 'unknown'}`);
      });
      const groupKey = groupKeyParts.join('|');

      // 如果组不存在，创建一个新的
      if (!groupedData[groupKey]) {
        groupedData[groupKey] = {
          date: item.date,
          templateName: checkedDimensions.includes('templateName')
            ? item.templateName
            : undefined,
          strategyName: checkedDimensions.includes('strategyName')
            ? item.strategyName
            : undefined,
          cc: checkedDimensions.includes('cc') ? item.cc : undefined,
          image: checkedDimensions.includes('image') ? item.image : undefined,
          totalRecords: 0,
          sent: 0,
          delivered: 0,
          opened: 0,
          failed: 0,
          displayCount: 0,
          sentSuccessRate: 0,
          deliveredRate: 0,
          displayRate: 0,
          clickThroughRate: 0,
          tokenInvalidationRate: 0,
        };
      }

      // 累加数据
      const group = groupedData[groupKey];
      group.totalRecords += item.totalRecords;
      group.sent += item.sent;
      group.delivered += item.delivered;
      group.opened += item.opened;
      group.failed += item.failed;
      group.displayCount += item.displayCount;

      // 比率取加权平均
      group.sentSuccessRate = this.calculateWeightedAverage(
        group.sentSuccessRate,
        group.totalRecords - item.totalRecords,
        item.sentSuccessRate,
        item.totalRecords
      );

      group.deliveredRate = this.calculateWeightedAverage(
        group.deliveredRate,
        group.sent - item.sent,
        item.deliveredRate,
        item.sent
      );

      group.clickThroughRate = this.calculateWeightedAverage(
        group.clickThroughRate,
        group.displayCount - item.displayCount,
        item.clickThroughRate,
        item.displayCount
      );
    });

    return Object.values(groupedData).sort(
      (a, b) => new Date(b.date).getTime() - new Date(a.date).getTime()
    );
  }

  /**
   * 计算加权平均值
   */
  private calculateWeightedAverage(
    currentAvg: number,
    currentTotal: number,
    newValue: number,
    newTotal: number
  ): number {
    if (currentTotal + newTotal === 0) return 0;
    return (
      (currentAvg * currentTotal + newValue * newTotal) /
      (currentTotal + newTotal)
    );
  }

  /**
   * 提取可用的筛选选项
   */
  extractAvailableOptions(): void {
    const templates = new Set<string>();
    const strategies = new Set<string>();
    const countries = new Set<string>();
    const images = new Set<string>();

    this.statsData.forEach((item) => {
      if (item.templateName) templates.add(item.templateName);
      if (item.strategyName) strategies.add(item.strategyName);
      if (item.cc) countries.add(item.cc);
      if (item.image) images.add(item.image);
    });

    this.availableTemplates = Array.from(templates).sort();
    this.availableStrategies = Array.from(strategies).sort();
    this.availableCountries = Array.from(countries).sort();
    this.availableImages = Array.from(images).sort();
  }

  /**
   * 计算汇总统计
   */
  calculateSummaryStats(): void {
    if (!this.filteredStats.length) {
      this.summaryStats = null;
      return;
    }

    const summary = {
      totalRecords: 0,
      sent: 0,
      delivered: 0,
      opened: 0,
      failed: 0,
      displayCount: 0,
      sentSuccessRate: 0,
      deliveredRate: 0,
      displayRate: 0,
      clickThroughRate: 0,
      tokenInvalidationRate: 0,
    };

    this.filteredStats.forEach((item) => {
      summary.totalRecords += item.totalRecords;
      summary.sent += item.sent;
      summary.delivered += item.delivered;
      summary.opened += item.opened;
      summary.failed += item.failed;
      summary.displayCount += item.displayCount;
    });

    // 计算汇总比率
    summary.sentSuccessRate =
      summary.totalRecords > 0 ? summary.sent / summary.totalRecords : 0;
    summary.deliveredRate =
      summary.sent > 0 ? summary.delivered / summary.sent : 0;
    summary.displayRate =
      summary.delivered > 0 ? summary.displayCount / summary.delivered : 0;
    summary.clickThroughRate =
      summary.displayCount > 0 ? summary.opened / summary.displayCount : 0;
    summary.tokenInvalidationRate =
      summary.totalRecords > 0 ? summary.failed / summary.totalRecords : 0;

    this.summaryStats = summary;
  }

  /**
   * 更新图表数据
   */
  updateChartData(): void {
    // 按日期分组数据
    const dateGroups: { [key: string]: MultiDimensionalStats } = {};

    this.filteredStats.forEach((item) => {
      if (!dateGroups[item.date]) {
        dateGroups[item.date] = {
          ...item,
          totalRecords: 0,
          sent: 0,
          delivered: 0,
          opened: 0,
          failed: 0,
          displayCount: 0,
        };
      }

      const group = dateGroups[item.date];
      group.totalRecords += item.totalRecords;
      group.sent += item.sent;
      group.delivered += item.delivered;
      group.opened += item.opened;
      group.failed += item.failed;
      group.displayCount += item.displayCount;
      group.deliveredRate = item.deliveredRate;
      group.clickThroughRate = item.clickThroughRate;
    });

    // 排序日期
    const sortedDates = Object.keys(dateGroups).sort(
      (a, b) => new Date(a).getTime() - new Date(b).getTime()
    );

    // 更新图表数据
    this.chartData.labels = sortedDates.map((date) =>
      new Date(date).toLocaleDateString()
    );
    this.chartData.datasets[0].data = sortedDates.map(
      (date) => dateGroups[date].totalRecords
    );
    this.chartData.datasets[1].data = sortedDates.map(
      (date) => dateGroups[date].sent
    );
    this.chartData.datasets[2].data = sortedDates.map(
      (date) => dateGroups[date].delivered
    );
    this.chartData.datasets[3].data = sortedDates.map(
      (date) => dateGroups[date].displayCount
    );
    this.chartData.datasets[4].data = sortedDates.map(
      (date) => dateGroups[date].opened
    );
    this.chartData.datasets[5].data = sortedDates.map(
      (date) => dateGroups[date].failed
    );
    this.chartData.datasets[6].data = sortedDates.map(
      (date) => dateGroups[date].deliveredRate
    );
    this.chartData.datasets[7].data = sortedDates.map(
      (date) => dateGroups[date].clickThroughRate
    );
  }

  /**
   * 处理日期范围变化
   */
  onDateRangeChange(dateRange: Date[]): void {
    this.dateRange = dateRange;
    this.filters.startDate = dateRange[0] || undefined;
    this.filters.endDate = dateRange[1] || undefined;

    if (this.isDateRangeValid()) {
      this.loadStatistics();
    }
  }

  /**
   * 验证日期范围有效性
   */
  private isDateRangeValid(): boolean {
    if (!this.filters.startDate || !this.filters.endDate) {
      return true;
    }

    const start = new Date(this.filters.startDate);
    const end = new Date(this.filters.endDate);

    if (end < start) {
      this.message.error('结束日期不能早于开始日期，请重新选择');
      return false;
    }

    return true;
  }

  /**
   * 重置筛选条件
   */
  resetFilters(): void {
    this.filters = {
      startDate: this.dateRange[0],
      endDate: this.dateRange[1],
    };
    this.loadStatistics();
  }

  /**
   * 处理维度选择变化
   */
  onDimensionChange(): void {
    this.processData();
  }

  /**
   * 表格排序
   */
  sortTable(field: string): void {
    if (this.sortField === field) {
      this.sortDirection =
        this.sortDirection === 'ascend' ? 'descend' : 'ascend';
    } else {
      this.sortField = field;
      this.sortDirection = 'ascend';
    }

    this.filteredStats.sort((a, b) => {
      const valueA = (a as any)[this.sortField!] || '';
      const valueB = (b as any)[this.sortField!] || '';

      if (typeof valueA === 'number' && typeof valueB === 'number') {
        return this.sortDirection === 'ascend'
          ? valueA - valueB
          : valueB - valueA;
      }

      const strA = String(valueA).toLowerCase();
      const strB = String(valueB).toLowerCase();
      return this.sortDirection === 'ascend'
        ? strA.localeCompare(strB)
        : strB.localeCompare(strA);
    });
  }

  /**
   * 格式化国家显示
   */
  formatCountry(cc: string): string {
    if (!cc) return '未知';

    const code = cc.toUpperCase();
    const countryName =
      countries.getName(code, 'zh') ||
      countries.getName(code, 'en') ||
      '未知国家';

    return `${countryName}(${code})`;
  }

  /**
   * 格式化百分比
   */
  formatPercentage(value: number): string {
    return (value * 100).toFixed(2) + '%';
  }

  /**
   * 为API格式化日期
   */
  private formatDateForApi(date: Date): string {
    return date.toISOString().split('T')[0];
  }

  /**
   * 获取排序图标
   */
  getSortIcon(field: string): 'sort-ascending' | 'sort-descending' | null {
    if (this.sortField == field) {
      return this.sortDirection == 'ascend'
        ? 'sort-ascending'
        : 'sort-descending';
    }
    return null;
  }

  // 在组件类中添加图片加载错误处理方法
  handleImageError(event: Event): void {
    // 当图片加载失败时显示默认占位图
    const imgElement = event.target as HTMLImageElement;
    imgElement.src =
      'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyMDAgMjAwIj48cGF0aCBkPSJNMTk5IDEwMEgyMWE5OSA5OSAwIDAgMS05OS05OXYzYzAgMTEwLjUgOTkgMjAwIDE5OSAxOTl2LTNjMTAwLjUtMTAwIDE5OS0xOTkgMTk5LTE5OXptLTE1OSA1OGwtMzctMzdsMzctMzdjMy0zIDgtMyAxMSAwbDMyIDMyYzMgMyAzIDggMCAxMWwtMzcgMzdjLTMgMy04IDMtMTEgMHptLTUyLTk1YzAgMTMuMy0xMC43IDI0LTI0IDI0cy0yNC0xMC43LTI0LTI0IDEwLjctMjQgMjQtMjQgMjQgMTAuNyAyNCAyNC0xMC43IDI0LTI0IDI0eiIvPjwvc3ZnPg==';
    imgElement.alt = '图片无法加载';
  }
}
