import { Component, OnInit } from '@angular/core';
import { CommonModule, NgFor, NgIf, DatePipe } from '@angular/common';
import { DashboardService, NewArtworkTab } from '../services/dashboard.service';
import { ArtDoneRateComponent } from './art-done-rate.component';

import { NzCardModule } from 'ng-zorro-antd/card';
import { NzIconModule } from 'ng-zorro-antd/icon';
import { NzStatisticModule } from 'ng-zorro-antd/statistic';
import { NzSpinModule } from 'ng-zorro-antd/spin';
import { NzTableModule } from 'ng-zorro-antd/table';
import { NzPageHeaderModule } from 'ng-zorro-antd/page-header';
import { NzTabsModule } from 'ng-zorro-antd/tabs';
import { NzMessageService } from 'ng-zorro-antd/message';

@Component({
  selector: 'app-dashboard',
  standalone: true,
  imports: [
    CommonModule,
    NgFor,
    NgIf,
    DatePipe,
    ArtDoneRateComponent,
    NzCardModule,
    NzIconModule,
    NzStatisticModule,
    NzSpinModule,
    NzTableModule,
    NzPageHeaderModule,
    NzTabsModule,
  ],
  providers: [NzMessageService],
  template: `
    <div class="dashboard-container">
      <nz-page-header [nzGhost]="false">
        <nz-page-header-title>数据看板</nz-page-header-title>
        <nz-page-header-extra>
          <span nz-icon nzType="sync" nzTheme="outline" (click)="refreshData()"></span>
        </nz-page-header-extra>
        <nz-page-header-content>
          <p>最后更新时间：{{ lastUpdateTime | date: 'yyyy-MM-dd HH:mm:ss' }}</p>
        </nz-page-header-content>
      </nz-page-header>

      <nz-spin [nzSpinning]="isLoading" nzTip="数据加载中...">
        <nz-card nzTitle="用户卡片：当日日活 + 日活曲线" nzHoverable class="stack-card">
          <nz-statistic
            [nzTitle]="'当日日活(DAU)'"
            [nzValue]="activeUsersToday"
            [nzPrefix]="userIcon"
            [nzSuffix]="'人'"
            [nzValueStyle]="{ color: '#1677ff' }"
          ></nz-statistic>
          <ng-template #userIcon>
            <span nz-icon nzType="user" nzTheme="outline"></span>
          </ng-template>

          <div class="range-buttons">
            <button type="button" class="range-btn" [class.active]="selectedDauRange === 7" (click)="changeDauRange(7)">7天</button>
            <button type="button" class="range-btn" [class.active]="selectedDauRange === 14" (click)="changeDauRange(14)">14天</button>
            <button type="button" class="range-btn" [class.active]="selectedDauRange === 30" (click)="changeDauRange(30)">30天</button>
          </div>

          <div class="chart-wrapper">
            <svg viewBox="0 0 600 180" class="line-chart" preserveAspectRatio="none">
              <polyline
                *ngIf="dauChartPoints"
                [attr.points]="dauChartPoints"
                fill="none"
                stroke="#1677ff"
                stroke-width="3"
                stroke-linecap="round"
                stroke-linejoin="round"
              ></polyline>
              <line
                *ngIf="hoveredDauIndex >= 0"
                [attr.x1]="hoveredDauX"
                [attr.y1]="16"
                [attr.x2]="hoveredDauX"
                [attr.y2]="164"
                stroke="#91caff"
                stroke-width="1"
                stroke-dasharray="3 3"
              ></line>
              <circle
                *ngIf="hoveredDauIndex >= 0"
                [attr.cx]="hoveredDauX"
                [attr.cy]="hoveredDauY"
                r="4"
                fill="#1677ff"
              ></circle>
              <rect
                x="0"
                y="0"
                width="600"
                height="180"
                fill="transparent"
                (mousemove)="onChartMouseMove($event)"
                (mouseleave)="onChartMouseLeave()"
              ></rect>
            </svg>
          </div>

          <div class="chart-hover-tip" *ngIf="hoveredDauIndex >= 0">
            {{ hoveredDauDate }}：{{ hoveredDauValue }}
          </div>

          <div class="chart-meta">
            <span>{{ dauTrendStartDate }}</span>
            <span>Max: {{ dauMax }}</span>
            <span>Min: {{ dauMin }}</span>
            <span>{{ dauTrendEndDate }}</span>
          </div>
        </nz-card>

        <nz-card nzTitle="作品卡片：最近7天上新作品表现" nzHoverable class="stack-card">
          <nz-tabset [nzSelectedIndex]="activeArtworkTabIndex" (nzSelectedIndexChange)="activeArtworkTabIndex = $event">
            <nz-tab *ngFor="let tab of artworkTabs" [nzTitle]="tab.label">
              <div class="tab-subtitle">{{ tab.date }} · 当日DAU {{ tab.dau }}</div>

              <nz-table
                #worksTable
                [nzData]="tab.artworks"
                [nzFrontPagination]="false"
                [nzBordered]="true"
                [nzSize]="'small'"
              >
                <thead>
                  <tr>
                    <th>作品</th>
                    <th>名称</th>
                    <th>区块数</th>
                    <th>点击率</th>
                    <th>完成率</th>
                    <th>点击数</th>
                    <th>完成数</th>
                    <th>道具使用数</th>
                  </tr>
                </thead>
                <tbody>
                  <tr *ngFor="let work of worksTable.data">
                    <td>
                      <img
                        [src]="work.thumbnail"
                        class="work-thumbnail"
                        alt="作品缩略图"
                        (click)="openArtworkImage(work.thumbnail)"
                      />
                    </td>
                    <td>
                      <a [href]="getArtworkDetailUrl(work.resId)" target="_blank" rel="noopener noreferrer">
                        {{ work.name }}
                      </a>
                    </td>
                    <td>{{ work.areaCount || 0 }}</td>
                    <td>{{ work.clickRate * 100 | number: '1.1-2' }}%</td>
                    <td>
                      <art-done-rate
                        [data]="{
                          completionRate: work.completionRate,
                          areaCountFloor: work.areaCountFloor,
                          totalStartCount: work.clickCount,
                          totalDoneCount: work.completionCount
                        }"
                      ></art-done-rate>
                    </td>
                    <td>{{ work.clickCount }}</td>
                    <td>{{ work.completionCount }}</td>
                    <td>{{ work.tipCount || 0 }}</td>
                  </tr>
                </tbody>
              </nz-table>

              <div class="empty-tip" *ngIf="tab.artworks.length === 0">当日无上新作品</div>
            </nz-tab>
          </nz-tabset>
        </nz-card>
      </nz-spin>
    </div>
  `,
  styles: [
    `
      .dashboard-container {
        padding: 24px;
        background: #f5f7fa;
        min-height: 100%;
      }

      .stack-card {
        margin-bottom: 16px;
      }

      .range-buttons {
        margin: 12px 0 8px;
        display: flex;
        gap: 8px;
      }

      .range-btn {
        border: 1px solid #d9d9d9;
        background: #fff;
        border-radius: 6px;
        padding: 4px 10px;
        cursor: pointer;
      }

      .range-btn.active {
        border-color: #1677ff;
        color: #1677ff;
        background: #e6f4ff;
      }

      .chart-wrapper {
        margin-top: 8px;
        border: 1px solid #f0f0f0;
        border-radius: 8px;
        background: #fcfdff;
      }

      .line-chart {
        width: 100%;
        height: 180px;
      }

      .chart-meta {
        margin-top: 8px;
        display: flex;
        justify-content: space-between;
        color: #8c8c8c;
        font-size: 12px;
      }

      .chart-hover-tip {
        margin-top: 6px;
        color: #262626;
        font-size: 12px;
      }

      .tab-subtitle {
        margin-bottom: 10px;
        color: #595959;
        font-size: 12px;
      }

      .work-thumbnail {
        width: 52px;
        height: 52px;
        border-radius: 4px;
        object-fit: cover;
        border: 1px solid #f0f0f0;
        cursor: zoom-in;
      }

      .empty-tip {
        margin-top: 10px;
        color: #8c8c8c;
        font-size: 12px;
      }
    `,
  ],
})
export class DashboardComponent implements OnInit {
  isLoading = true;
  lastUpdateTime = new Date();

  activeUsersToday = 0;
  selectedDauRange = 30;

  dauTrendData: number[] = [];
  dauTrendLabels: string[] = [];
  dauChartPoints = '';
  dauMin = 0;
  dauMax = 0;
  dauTrendStartDate = '';
  dauTrendEndDate = '';
  hoveredDauIndex = -1;
  hoveredDauX = 0;
  hoveredDauY = 0;
  hoveredDauDate = '';
  hoveredDauValue = 0;

  artworkTabs: NewArtworkTab[] = [];
  activeArtworkTabIndex = 0;

  private readonly chartWidth = 600;
  private readonly chartHeight = 180;
  private readonly chartPadding = 16;

  constructor(
    private message: NzMessageService,
    private dashboardService: DashboardService,
  ) {}

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

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

  changeDauRange(days: number): void {
    if (this.selectedDauRange === days) return;
    this.selectedDauRange = days;
    this.loadUserCardData();
  }

  private buildDauChartPoints(values: number[]): string {
    if (!values.length) return '';

    const width = 600;
    const height = 180;
    const padding = 16;
    const minVal = Math.min(...values);
    const maxVal = Math.max(...values);
    const span = Math.max(1, maxVal - minVal);
    const stepX =
      values.length > 1 ? (width - padding * 2) / (values.length - 1) : 0;

    return values
      .map((value, idx) => {
        const x = padding + idx * stepX;
        const y =
          height - padding - ((value - minVal) / span) * (height - padding * 2);
        return `${x},${y}`;
      })
      .join(' ');
  }

  private getDauY(value: number): number {
    const minVal = this.dauMin;
    const maxVal = this.dauMax;
    const span = Math.max(1, maxVal - minVal);
    return this.chartHeight - this.chartPadding - ((value - minVal) / span) * (this.chartHeight - this.chartPadding * 2);
  }

  onChartMouseMove(event: MouseEvent): void {
    if (this.dauTrendData.length === 0) return;

    const rect = (event.target as SVGRectElement).getBoundingClientRect();
    const localX = ((event.clientX - rect.left) / rect.width) * this.chartWidth;

    let index = 0;
    if (this.dauTrendData.length > 1) {
      const stepX = (this.chartWidth - this.chartPadding * 2) / (this.dauTrendData.length - 1);
      index = Math.round((localX - this.chartPadding) / stepX);
      index = Math.max(0, Math.min(this.dauTrendData.length - 1, index));
      this.hoveredDauX = this.chartPadding + index * stepX;
    } else {
      this.hoveredDauX = this.chartWidth / 2;
    }

    this.hoveredDauIndex = index;
    this.hoveredDauDate = this.dauTrendLabels[index] || '';
    this.hoveredDauValue = this.dauTrendData[index] || 0;
    this.hoveredDauY = this.getDauY(this.hoveredDauValue);
  }

  onChartMouseLeave(): void {
    this.hoveredDauIndex = -1;
  }

  getArtworkDetailUrl(resId: string): string {
    return `https://color2.jccytech.cn/app/zh/pages/detail/${resId}`;
  }

  openArtworkImage(imageUrl: string): void {
    if (!imageUrl) return;
    window.open(imageUrl, '_blank', 'noopener,noreferrer');
  }

  private applyDauData(dau: { today: number; trend: Array<{ date: string; dau: number }> }): void {
    this.activeUsersToday = dau.today;
    this.dauTrendLabels = dau.trend.map((item) => item.date);
    this.dauTrendData = dau.trend.map((item) => item.dau);
    this.dauMin = this.dauTrendData.length
      ? Math.min(...this.dauTrendData)
      : 0;
    this.dauMax = this.dauTrendData.length
      ? Math.max(...this.dauTrendData)
      : 0;
    this.dauTrendStartDate = this.dauTrendLabels[0] || '';
    this.dauTrendEndDate =
      this.dauTrendLabels[this.dauTrendLabels.length - 1] || '';
    this.dauChartPoints = this.buildDauChartPoints(this.dauTrendData);
  }

  private loadUserCardData(): void {
    this.isLoading = true;
    this.dashboardService.getKpi(this.selectedDauRange).subscribe({
      next: (response) => {
        if (!response.success) {
          this.message.error('获取日活数据失败');
          this.isLoading = false;
          return;
        }

        this.applyDauData(response.data.dau);
        this.lastUpdateTime = new Date();
        this.isLoading = false;
      },
      error: (error) => {
        console.error('Failed to load DAU data:', error);
        this.message.error('加载日活数据出错');
        this.isLoading = false;
      },
    });
  }

  private loadArtworkTabsData(): Promise<void> {
    return new Promise((resolve) => {
      this.dashboardService.getNewArtworkTabs(7, 20).subscribe({
        next: (response) => {
          if (response.success) {
            this.artworkTabs = response.data.tabs || [];
            this.activeArtworkTabIndex = 0;
          } else {
            this.message.error('获取上新作品数据失败');
          }
          resolve();
        },
        error: (error) => {
          console.error('Failed to load artwork tabs:', error);
          this.message.error('加载上新作品数据出错');
          resolve();
        },
      });
    });
  }

  loadDashboardData(): void {
    this.isLoading = true;
    this.dashboardService.getKpi(this.selectedDauRange).subscribe({
      next: async (kpiResponse) => {
        if (!kpiResponse.success) {
          this.message.error('获取日活数据失败');
          this.isLoading = false;
          return;
        }

        this.applyDauData(kpiResponse.data.dau);
        await this.loadArtworkTabsData();

        this.lastUpdateTime = new Date();
        this.isLoading = false;
      },
      error: (error) => {
        console.error('Failed to load dashboard data:', error);
        this.message.error('加载看板数据出错');
        this.isLoading = false;
      },
    });
  }
}
