import { Component, OnInit, signal, computed, Inject, ViewChild, ElementRef, OnDestroy, NgZone, ChangeDetectorRef, AfterViewInit } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { MatButtonModule } from '@angular/material/button';
import { MatTabsModule } from '@angular/material/tabs';
import { MatIconModule } from '@angular/material/icon';
import { MatTableModule } from '@angular/material/table';
import { MatCardModule } from '@angular/material/card';
import { MatTooltipModule } from '@angular/material/tooltip';
import { MatDialogModule, MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
import { Attendance as AttendanceModel, Employee } from '../../../models/hr.model';
import * as echarts from 'echarts';

// 补卡申请对话框组件
@Component({
  selector: 'app-attendance-dialog',
  standalone: true,
  imports: [
    CommonModule,
    FormsModule,
    MatButtonModule,
    MatIconModule
  ],
  template: `
    <div class="dialog-header">
      <h2>补卡申请</h2>
      <button class="close-btn" (click)="dialogRef.close()">
        <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
          <line x1="18" y1="6" x2="6" y2="18"></line>
          <line x1="6" y1="6" x2="18" y2="18"></line>
        </svg>
      </button>
    </div>
    <div class="dialog-content">
      <div class="info-item">
        <label>员工姓名:</label>
        <span>{{ attendanceData.employeeName }}</span>
      </div>
      <div class="info-item">
        <label>异常日期:</label>
        <span>{{ formatDate(attendanceData.date) }}</span>
      </div>
      <div class="info-item">
        <label>异常类型:</label>
        <span>{{ attendanceData.status }}</span>
      </div>
      <div class="form-group">
        <label>补卡说明:</label>
        <textarea 
          [(ngModel)]="reason" 
          placeholder="请输入补卡原因..." 
          rows="3"
          class="reason-input"
        ></textarea>
      </div>
    </div>
    <div class="dialog-actions">
      <button mat-button (click)="dialogRef.close()">取消</button>
      <button mat-raised-button color="primary" (click)="submit()">提交申请</button>
    </div>
  `,
  styles: [`
    .dialog-header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      margin-bottom: 24px;
      padding-bottom: 16px;
      border-bottom: 1px solid #e5e7eb;
    }
    .close-btn {
      background: none;
      border: none;
      cursor: pointer;
      color: #6b7280;
      padding: 4px;
    }
    .dialog-content {
      max-width: 500px;
    }
    .info-item {
      display: flex;
      justify-content: space-between;
      margin-bottom: 12px;
      padding: 8px 0;
      border-bottom: 1px solid #f3f4f6;
    }
    .form-group {
      margin-top: 20px;
    }
    label {
      display: block;
      margin-bottom: 4px;
      font-weight: 500;
      color: #374151;
    }
    .reason-input {
      width: 100%;
      padding: 8px 12px;
      border: 1px solid #e5e7eb;
      border-radius: 6px;
      font-size: 14px;
      resize: vertical;
    }
    .dialog-actions {
      display: flex;
      justify-content: flex-end;
      gap: 12px;
      margin-top: 24px;
    }
  `]
}) class AttendanceDialog {
  attendanceData: any;
  reason = '';
  
  constructor(
    public dialogRef: MatDialogRef<AttendanceDialog>,
    @Inject(MAT_DIALOG_DATA) public data: any
  ) {
    this.attendanceData = data;
  }
  
  formatDate(date: Date | string): string {
    if (!date) return '';
    const d = new Date(date);
    return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;
  }
  
  submit() {
    if (!this.reason.trim()) {
      alert('请输入补卡原因');
      return;
    }
    this.dialogRef.close({ reason: this.reason });
  }
}

// 生成模拟考勤数据
const generateMockAttendanceData = (): AttendanceModel[] => {
  const statuses: Array<'正常' | '迟到' | '早退' | '旷工' | '请假'> = ['正常', '迟到', '早退', '旷工', '请假'];
  const attendanceList: AttendanceModel[] = [];
  const today = new Date();
  const projectIds = ['proj-001', 'proj-002', 'proj-003', 'proj-004'];
  const projectNames = ['现代风格客厅设计', '欧式厨房改造', '极简卧室设计', '办公室规划'];
  
  // 生成最近30天的考勤数据
  for (let i = 29; i >= 0; i--) {
    const date = new Date();
    date.setDate(today.getDate() - i);
    
    // 为每个部门生成3-5个员工的考勤数据
    const departmentCount = Math.floor(Math.random() * 3) + 3;
    
    for (let j = 1; j <= departmentCount; j++) {
      const statusIndex = Math.floor(Math.random() * 10);
      let status: typeof statuses[0];
      
      // 80%概率正常，10%概率迟到，5%概率早退，3%概率请假，2%概率旷工
      if (statusIndex < 8) {
        status = '正常';
      } else if (statusIndex < 9) {
        status = '迟到';
      } else if (statusIndex < 9.5) {
        status = '早退';
      } else if (statusIndex < 9.8) {
        status = '请假';
      } else {
        status = '旷工';
      }
      
      // 随机选择一个项目
      const projectIndex = Math.floor(Math.random() * projectIds.length);
      const projectId = projectIds[projectIndex];
      const projectName = projectNames[projectIndex];
      
      // 生成打卡时间
      let checkInTime: Date | undefined;
      let checkOutTime: Date | undefined;
      let workHours = 0;
      
      if (status !== '旷工' && status !== '请假') {
        checkInTime = new Date(date);
        checkInTime.setHours(9 + (status === '迟到' ? Math.floor(Math.random() * 2) : 0));
        checkInTime.setMinutes(Math.floor(Math.random() * 60));
        
        checkOutTime = new Date(date);
        checkOutTime.setHours(18 - (status === '早退' ? Math.floor(Math.random() * 2) : 0));
        checkOutTime.setMinutes(Math.floor(Math.random() * 60));
        
        // 计算工作时长（小时）
        workHours = Math.round((checkOutTime.getTime() - checkInTime.getTime()) / (1000 * 60 * 60) * 10) / 10;
      }
      
      attendanceList.push({
        id: `att-${date.getTime()}-${j}`,
        employeeId: `emp-${j}`,
        date,
        checkInTime,
        checkOutTime,
        status,
        workHours,
        projectId,
        projectName
      });
    }
  }
  
  return attendanceList;
};

// 生成模拟员工数据
const generateMockEmployees = (): Employee[] => {
  const employees: Employee[] = [];
  const departments = ['设计部', '客户服务部', '财务部', '人力资源部'];
  const positions = ['设计师', '客服专员', '财务专员', '人事专员', '经理', '助理'];
  const names = ['张三', '李四', '王五', '赵六', '钱七', '孙八', '周九', '吴十'];
  
  for (let i = 1; i <= 20; i++) {
    employees.push({
      id: `emp-${i}`,
      name: names[i % names.length] + i,
      department: departments[Math.floor(Math.random() * departments.length)],
      position: positions[Math.floor(Math.random() * positions.length)],
      employeeId: `EMP2023${String(i).padStart(3, '0')}`,
      phone: `138${Math.floor(Math.random() * 100000000)}`,
      email: `employee${i}@example.com`,
      gender: i % 2 === 0 ? '女' : '男',
      birthDate: new Date(1980 + Math.floor(Math.random() * 20), Math.floor(Math.random() * 12), Math.floor(Math.random() * 28) + 1),
      hireDate: new Date(2020 + Math.floor(Math.random() * 3), Math.floor(Math.random() * 12), Math.floor(Math.random() * 28) + 1),
      status: '在职',
      avatar: `https://via.placeholder.com/40?text=${i}`
    });
  }
  
  return employees;
};

// 主组件
@Component({
  selector: 'app-attendance',
  standalone: true,
  imports: [
    CommonModule,
    FormsModule,
    MatButtonModule,
    MatTabsModule,
    MatIconModule,
    MatTableModule,
    MatCardModule,
    MatTooltipModule,
    MatDialogModule
  ],
  templateUrl: './attendance.html',
  styleUrl: './attendance.scss'
}) export class Attendance implements OnDestroy, OnInit, AfterViewInit {
  @ViewChild('ganttChartRef') ganttChartRef!: ElementRef;
  private ganttChart: any = null;
  private onResize = () => {
    if (this.ganttChart) {
      this.ganttChart.resize();
    }
  };
  private onChartClick = (params: any) => {
    this.zone.run(() => {
      const v = params?.value;
      if (!v) return;
      const start = new Date(v[1]);
      const end = new Date(v[2]);
      const employee = v[3];
      const progress = v[4];
      alert(`任务：${params.name}\n负责人：${employee}\n进度：${progress}%\n起止：${start.toLocaleDateString()} ~ ${end.toLocaleDateString()}`);
    });
  };
  showGanttView = signal(false);
  ganttScale = signal<'day' | 'week' | 'month'>('week');
  ganttMode = signal<'attendance' | 'workload'>('attendance');
  selectedDepartment = 'all';
  
  // 数据
  attendanceData = signal<AttendanceModel[]>(generateMockAttendanceData());
  employees = signal<Employee[]>(generateMockEmployees());
  
  // 计算属性
  departments = computed(() => {
    const depts = new Set(this.employees().map(emp => emp.department));
    return Array.from(depts).sort();
  });
  
  filteredEmployees = computed(() => {
    if (this.selectedDepartment === 'all') {
      return this.employees();
    }
    return this.employees().filter(emp => emp.department === this.selectedDepartment);
  });
  selectedView = signal<'day' | 'week' | 'month'>('month');
  selectedDate = signal<Date>(new Date());
  selectedEmployeeId = signal<string>('');
  selectedProjectId = signal<string>('');
  
  // 通过computed缓存当月日历，避免模板每次变更检测都创建新数组
  calendarDays = computed(() => this.computeCalendarDays());
  
  // 获取日期tooltip信息
  getDayTooltip(day: any): string {
    if (!day.attendance) {
      return '休息日';
    }
    
    const status = day.attendance.status;
    let tooltip = `状态: ${status}`;
    
    if (day.attendance.workHours) {
      tooltip += `\n工作时长: ${day.attendance.workHours}小时`;
    }
    
    if (day.attendance.checkInTime) {
      const checkIn = new Date(day.attendance.checkInTime);
      tooltip += `\n签到: ${checkIn.getHours().toString().padStart(2, '0')}:${checkIn.getMinutes().toString().padStart(2, '0')}`;
    }
    
    if (day.attendance.checkOutTime) {
      const checkOut = new Date(day.attendance.checkOutTime);
      tooltip += `\n签退: ${checkOut.getHours().toString().padStart(2, '0')}:${checkOut.getMinutes().toString().padStart(2, '0')}`;
    }
    
    if (day.attendance.projectName) {
      tooltip += `\n项目: ${day.attendance.projectName}`;
    }
    
    return tooltip;
  }
  
  // 检查日期是否为今天
  isToday(date: Date): boolean {
    const today = new Date();
    const checkDate = new Date(date);
    return today.toDateString() === checkDate.toDateString();
  }
  
  // 计算属性
  filteredAttendance = computed(() => {
    let filtered = this.attendanceData();
    
    // 按员工筛选
    if (this.selectedEmployeeId()) {
      filtered = filtered.filter(item => item.employeeId === this.selectedEmployeeId());
    }
    
    // 按项目筛选
    if (this.selectedProjectId()) {
      filtered = filtered.filter(item => item.projectId === this.selectedProjectId());
    }
    
    // 按视图筛选（日/周/月）
    const selectedDate = this.selectedDate();
    if (this.selectedView() === 'day') {
      filtered = filtered.filter(item => {
        const itemDate = new Date(item.date);
        return itemDate.getDate() === selectedDate.getDate() &&
               itemDate.getMonth() === selectedDate.getMonth() &&
               itemDate.getFullYear() === selectedDate.getFullYear();
      });
    } else if (this.selectedView() === 'week') {
      // 获取本周的起止日期
      const startOfWeek = new Date(selectedDate);
      const day = startOfWeek.getDay() || 7; // 调整周日为7
      startOfWeek.setDate(startOfWeek.getDate() - day + 1);
      const endOfWeek = new Date(startOfWeek);
      endOfWeek.setDate(endOfWeek.getDate() + 6);
      
      filtered = filtered.filter(item => {
        const itemDate = new Date(item.date);
        return itemDate >= startOfWeek && itemDate <= endOfWeek;
      });
    } else if (this.selectedView() === 'month') {
      filtered = filtered.filter(item => {
        const itemDate = new Date(item.date);
        return itemDate.getMonth() === selectedDate.getMonth() &&
               itemDate.getFullYear() === selectedDate.getFullYear();
      });
    }
    
    return filtered;
  });
  
  // 异常考勤列表
  exceptionAttendance = computed(() => {
    return this.filteredAttendance().filter(item => 
      item.status === '迟到' || item.status === '早退' || item.status === '旷工'
    ).sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime());
  });
  
  // 考勤统计
  attendanceStats = computed(() => {
    const data = this.filteredAttendance();
    const totalDays = data.length;
    const normalDays = data.filter(item => item.status === '正常').length;
    const lateDays = data.filter(item => item.status === '迟到').length;
    const earlyLeaveDays = data.filter(item => item.status === '早退').length;
    const absentDays = data.filter(item => item.status === '旷工').length;
    const leaveDays = data.filter(item => item.status === '请假').length;
    
    const totalWorkHours = data.reduce((sum, item) => sum + item.workHours, 0);
    const avgWorkHours = totalDays > 0 ? (totalWorkHours / (totalDays - leaveDays - absentDays || 1)).toFixed(1) : '0.0';
    
    return {
      totalDays,
      normalDays,
      lateDays,
      earlyLeaveDays,
      absentDays,
      leaveDays,
      totalWorkHours: totalWorkHours.toFixed(1),
      avgWorkHours,
      complianceRate: totalDays > 0 ? Math.round((normalDays / totalDays) * 100) : 0
    };
  });
  
  // 部门考勤对比数据
  departmentAttendanceData = computed(() => {
    const departmentMap = new Map<string, { total: number; compliant: number }>();
    
    this.attendanceData().forEach(item => {
      const employee = this.employees().find(emp => emp.id === item.employeeId);
      if (employee) {
        const dept = employee.department;
        const current = departmentMap.get(dept) || { total: 0, compliant: 0 };
        current.total++;
        if (item.status === '正常') {
          current.compliant++;
        }
        departmentMap.set(dept, current);
      }
    });
    
    const result: { department: string; complianceRate: number; total: number; compliant: number }[] = [];
    departmentMap.forEach((value, key) => {
      result.push({
        department: key,
        complianceRate: Math.round((value.compliant / value.total) * 100),
        total: value.total,
        compliant: value.compliant
      });
    });
    
    return result.sort((a, b) => b.complianceRate - a.complianceRate);
  });
  
  // 显示的表格列
  displayedColumns = ['date', 'employeeName', 'status', 'workHours', 'projectName', 'actions'];
  
  constructor(private dialog: MatDialog, private zone: NgZone, private cdr: ChangeDetectorRef) {}
  
  ngOnInit() {
    // 已在字段声明处初始化模拟数据，避免首次变更检测期间的状态跃迁导致 ExpressionChanged
  }
  
  ngAfterViewInit() {
    // 稳定首次变更检测，避免控制流指令在初始化过程中值变化触发 NG0100
    this.cdr.detectChanges();
  }
  
  ngOnDestroy() {
    if (this.ganttChart) {
      this.ganttChart.off('click', this.onChartClick);
      this.ganttChart.dispose();
      this.ganttChart = null;
    }
    window.removeEventListener('resize', this.onResize);
  }
  
  // 移除 ngAfterViewInit 钩子
  
   // 切换视图（日/周/月）
  switchView(view: 'day' | 'week' | 'month') {
    this.selectedView.set(view);
    // 重置到当前日期
    this.selectedDate.set(new Date());
  }

  // 切换视图（考勤/任务）
  toggleView(target?: 'attendance' | 'task') {
    try {
      const next = target ? (target === 'task') : !this.showGanttView();
      this.showGanttView.set(next);
      
      if (next) {
        // 等待DOM渲染后初始化图表
        setTimeout(() => {
          try {
            this.initOrUpdateGantt();
          } catch (error) {
            console.error('甘特图初始化失败:', error);
          }
        }, 100);
      } else {
        this.cleanupGanttChart();
      }
    } catch (error) {
      console.error('视图切换失败:', error);
    }
  }

  // 清理甘特图资源
  private cleanupGanttChart() {
    try {
      if (this.ganttChart) {
        this.ganttChart.off('click', this.onChartClick);
        this.ganttChart.dispose();
        this.ganttChart = null;
        window.removeEventListener('resize', this.onResize);
      }
    } catch (error) {
      console.error('甘特图清理失败:', error);
    }
  }

  // 设置甘特时间尺度
  setGanttScale(scale: 'day' | 'week' | 'month') {
    if (this.ganttScale() !== scale) {
      this.ganttScale.set(scale);
      this.updateGantt();
    }
  }

  // 设置甘特图显示模式
  setGanttMode(mode: 'attendance' | 'workload') {
    if (this.ganttMode() !== mode) {
      this.ganttMode.set(mode);
      this.updateGantt();
    }
  }

  // 部门筛选变化
  onDepartmentChange() {
    this.updateGantt();
  }

  // 获取时间范围文本
  getTimeRangeText(): string {
    const date = this.selectedDate();
    const scale = this.ganttScale();
    
    if (scale === 'day') {
      return date.toLocaleDateString('zh-CN');
    } else if (scale === 'week') {
      const startOfWeek = new Date(date);
      const day = startOfWeek.getDay();
      const diff = startOfWeek.getDate() - day + (day === 0 ? -6 : 1);
      startOfWeek.setDate(diff);
      
      const endOfWeek = new Date(startOfWeek);
      endOfWeek.setDate(startOfWeek.getDate() + 6);
      
      return `${startOfWeek.toLocaleDateString('zh-CN')} - ${endOfWeek.toLocaleDateString('zh-CN')}`;
    } else {
      return `${date.getFullYear()}年${date.getMonth() + 1}月`;
    }
  }

  // 获取平均出勤率
  getAverageAttendanceRate(): number {
    const employees = this.filteredEmployees();
    if (employees.length === 0) return 0;
    
    const totalRate = employees.reduce((sum, emp) => {
      const empAttendance = this.attendanceData().filter(att => att.employeeId === emp.id);
      const normalDays = empAttendance.filter(att => att.status === '正常').length;
      const rate = empAttendance.length > 0 ? (normalDays / empAttendance.length) * 100 : 0;
      return sum + rate;
    }, 0);
    
    return Math.round(totalRate / employees.length);
  }

  // 获取平均工时
  getAverageWorkHours(): number {
    const employees = this.filteredEmployees();
    if (employees.length === 0) return 0;
    
    const totalHours = employees.reduce((sum, emp) => {
      const empAttendance = this.attendanceData().filter(att => att.employeeId === emp.id);
      const avgHours = empAttendance.reduce((h, att) => h + (att.workHours || 0), 0) / empAttendance.length;
      return sum + (avgHours || 0);
    }, 0);
    
    return Math.round((totalHours / employees.length) * 10) / 10;
  }
  
  // 获取员工姓名
  getEmployeeName(employeeId: string): string {
    const employee = this.employees().find(emp => emp.id === employeeId);
    return employee ? employee.name : '未知员工';
  }
  
  // 格式化日期
  formatDate(date: Date | string): string {
    if (!date) return '';
    const d = new Date(date);
    return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;
  }
  
  // 格式化时间
  formatTime(date: Date | string): string {
    if (!date) return '';
    const d = new Date(date);
    return `${String(d.getHours()).padStart(2, '0')}:${String(d.getMinutes()).padStart(2, '0')}`;
  }
  
  // 获取状态样式类
  getStatusClass(status: string): string {
    switch (status) {
      case '正常':
        return 'status-normal';
      case '迟到':
        return 'status-late';
      case '早退':
        return 'status-early';
      case '旷工':
        return 'status-absent';
      case '请假':
        return 'status-leave';
      default:
        return '';
    }
  }
  
  // 切换日期
  navigateDate(direction: 'prev' | 'next') {
    const newDate = new Date(this.selectedDate());
    
    if (this.selectedView() === 'day') {
      newDate.setDate(newDate.getDate() + (direction === 'prev' ? -1 : 1));
    } else if (this.selectedView() === 'week') {
      newDate.setDate(newDate.getDate() + (direction === 'prev' ? -7 : 7));
    } else if (this.selectedView() === 'month') {
      newDate.setMonth(newDate.getMonth() + (direction === 'prev' ? -1 : 1));
    }
    
    this.selectedDate.set(newDate);
  }
  
  private isDialogOpening = false;

  // 打开补卡申请对话框
  openAttendanceDialog(attendance: AttendanceModel) {
    // 防止重复点击
    if (this.isDialogOpening) {
      return;
    }
    
    try {
      this.isDialogOpening = true;
      const employee = this.employees().find(emp => emp.id === attendance.employeeId);
      
      const dialogRef = this.dialog.open(AttendanceDialog, {
        width: '500px',
        maxWidth: '90vw',
        disableClose: true,
        panelClass: 'hr-dialog',
        backdropClass: 'hr-dialog-backdrop',
        data: {
          ...attendance,
          employeeName: employee ? employee.name : '未知员工'
        }
      });
      
      dialogRef.afterClosed().subscribe({
        next: (result) => {
          this.isDialogOpening = false;
          if (result) {
            // 在实际应用中，这里会提交补卡申请到服务器
            alert('补卡申请已提交，等待审核');
          }
        },
        error: (error) => {
          this.isDialogOpening = false;
          console.error('对话框关闭时出错:', error);
        }
      });
    } catch (error) {
      this.isDialogOpening = false;
      console.error('打开补卡对话框失败:', error);
      alert('打开对话框失败，请重试');
    }
  }
  
  // 导出考勤数据
  exportAttendanceData(): void {
    try {
      const data = this.filteredAttendance();
      if (data.length === 0) {
        alert('暂无数据可导出');
        return;
      }
      
      const csvContent = this.convertToCSV(data);
      this.downloadCSV(csvContent, '考勤数据.csv');
      
      // 显示成功提示
      setTimeout(() => {
        alert(`成功导出 ${data.length} 条考勤记录`);
      }, 100);
    } catch (error) {
      console.error('导出数据失败:', error);
      alert('导出失败，请重试');
    }
  }

  // 将数据转换为CSV格式
  private convertToCSV(data: any[]): string {
    if (data.length === 0) return '';
    
    const headers = ['员工ID', '员工姓名', '日期', '上班时间', '下班时间', '状态', '工作时长', '所属项目'];
    const rows = data.map(item => {
      const employee = this.employees().find(emp => emp.id === item.employeeId);
      return [
        item.employeeId,
        employee ? employee.name : '未知员工',
        this.formatDate(item.date),
        item.checkInTime ? this.formatTime(item.checkInTime) : '',
        item.checkOutTime ? this.formatTime(item.checkOutTime) : '',
        item.status,
        item.workHours || '',
        item.projectName
      ];
    });
    
    return [headers, ...rows].map(row => row.map(field => `"${field}"`).join(',')).join('\n');
  }

  // 下载CSV文件
  private downloadCSV(csvContent: string, filename: string): void {
    const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
    const link = document.createElement('a');
    const url = URL.createObjectURL(blob);
    
    link.setAttribute('href', url);
    link.setAttribute('download', filename);
    link.style.visibility = 'hidden';
    
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
  }
  
  // 获取日历数据
  getCalendarDays() {
    return this.calendarDays();
  }
  
  // 实际计算日历数据
  private computeCalendarDays() {
    const year = this.selectedDate().getFullYear();
    const month = this.selectedDate().getMonth();
    
    // 获取当月第一天和最后一天
    const firstDay = new Date(year, month, 1);
    const lastDay = new Date(year, month + 1, 0);
    
    // 获取当月第一天是星期几
    const firstDayIndex = firstDay.getDay();
    
    const days: any[] = [];
    
    // 添加上月的最后几天
    for (let i = firstDayIndex; i > 0; i--) {
      const day = new Date(year, month, -i + 1);
      days.push({
        date: day,
        dayOfMonth: day.getDate(),
        currentMonth: false,
        attendance: null
      });
    }
    
    // 添加当月的天数
    for (let i = 1; i <= lastDay.getDate(); i++) {
      const day = new Date(year, month, i);
      const dayAttendance = this.attendanceData().filter(item => {
        const itemDate = new Date(item.date);
        return itemDate.getDate() === i &&
               itemDate.getMonth() === month &&
               itemDate.getFullYear() === year &&
               (!this.selectedEmployeeId() || item.employeeId === this.selectedEmployeeId());
      });
      
      days.push({
        date: day,
        dayOfMonth: i,
        currentMonth: true,
        attendance: dayAttendance.length > 0 ? dayAttendance[0] : null
      });
    }
    
    // 添加下月的前几天，凑够42天（6行7列）
    const remainingDays = 42 - days.length;
    for (let i = 1; i <= remainingDays; i++) {
      const day = new Date(year, month + 1, i);
      days.push({
        date: day,
        dayOfMonth: i,
        currentMonth: false,
        attendance: null
      });
    }
    
    return days;
  }
  
  // 获取星期几的中文名称
  getWeekdayName(index: number): string {
    const weekdays = ['日', '一', '二', '三', '四', '五', '六'];
    return weekdays[index];
  }

  private initOrUpdateGantt(): void {
    if (!this.ganttChartRef?.nativeElement) {
      console.warn('甘特图容器未找到');
      return;
    }
    
    const el = this.ganttChartRef.nativeElement;
    
    this.zone.runOutsideAngular(() => {
      try {
        if (!this.ganttChart) {
          // 检查容器尺寸
          if (el.offsetWidth === 0 || el.offsetHeight === 0) {
            console.warn('甘特图容器尺寸为0，延迟初始化');
            setTimeout(() => this.initOrUpdateGantt(), 200);
            return;
          }
          
          this.ganttChart = echarts.init(el);
          window.addEventListener('resize', this.onResize);
        }
        this.updateGantt();
      } catch (error) {
        console.error('甘特图初始化失败:', error);
      }
    });
  }

  private updateGantt(): void {
    if (!this.ganttChart) {
      console.warn('甘特图实例不存在');
      return;
    }
    
    try {
      // 工作负荷模式和考勤状态模式使用相同的数据结构，只是颜色映射不同

      // 考勤状态甘特图
      const employees = this.filteredEmployees();
      const categories = employees.map(emp => emp.name);
      
      // 考勤状态颜色映射
      const statusColorMap: Record<string, string> = {
        '正常': '#22c55e',
        '迟到': '#f59e0b', 
        '早退': '#f97316',
        '旷工': '#ef4444',
        '请假': '#8b5cf6',
        '加班': '#06b6d4'
      };

      const DAY = 24 * 60 * 60 * 1000;
      const now = new Date();
      const selectedDate = this.selectedDate();
      
      // 计算时间范围
      let xMin: number;
      let xMax: number;
      let xSplitNumber: number;
      let xLabelFormatter: (value: number) => string;

      if (this.ganttScale() === 'day') {
        // 日视图：显示当天的小时
        const startOfDay = new Date(selectedDate.getFullYear(), selectedDate.getMonth(), selectedDate.getDate());
        const endOfDay = new Date(startOfDay.getTime() + DAY - 1);
        xMin = startOfDay.getTime();
        xMax = endOfDay.getTime();
        xSplitNumber = 24;
        xLabelFormatter = (val) => `${new Date(val).getHours()}:00`;
      } else if (this.ganttScale() === 'week') {
        // 周视图：显示一周的天数
        const day = selectedDate.getDay();
        const diffToMonday = (day === 0 ? 6 : day - 1);
        const startOfWeek = new Date(selectedDate.getTime() - diffToMonday * DAY);
        const endOfWeek = new Date(startOfWeek.getTime() + 7 * DAY - 1);
        xMin = startOfWeek.getTime();
        xMax = endOfWeek.getTime();
        xSplitNumber = 7;
        const WEEK_LABELS = ['周日','周一','周二','周三','周四','周五','周六'];
        xLabelFormatter = (val) => WEEK_LABELS[new Date(val).getDay()];
      } else {
        // 月视图：显示一个月的周数
        const startOfMonth = new Date(selectedDate.getFullYear(), selectedDate.getMonth(), 1);
        const endOfMonth = new Date(selectedDate.getFullYear(), selectedDate.getMonth() + 1, 0, 23, 59, 59, 999);
        xMin = startOfMonth.getTime();
        xMax = endOfMonth.getTime();
        xSplitNumber = 4;
        xLabelFormatter = (val) => `第${Math.ceil(new Date(val).getDate() / 7)}周`;
      }

      // 生成考勤数据
      const data: any[] = [];
      employees.forEach((emp, empIndex) => {
        const empAttendance = this.attendanceData().filter(att => att.employeeId === emp.id);
        
        if (this.ganttScale() === 'day') {
          // 日视图：显示工作时间段
          const dayAttendance = empAttendance.find(att => {
            const attDate = new Date(att.date);
            return attDate.toDateString() === selectedDate.toDateString();
          });
          
          if (dayAttendance && dayAttendance.checkInTime && dayAttendance.checkOutTime) {
            const checkIn = new Date(`${selectedDate.toDateString()} ${dayAttendance.checkInTime}`);
            const checkOut = new Date(`${selectedDate.toDateString()} ${dayAttendance.checkOutTime}`);
            
            data.push({
              name: emp.name,
              value: [empIndex, checkIn.getTime(), checkOut.getTime(), dayAttendance.status, dayAttendance.workHours],
              itemStyle: { color: statusColorMap[dayAttendance.status] || '#94a3b8' }
            });
          }
        } else {
          // 周视图和月视图：显示每天的考勤状态
          const timeRange = this.ganttScale() === 'week' ? 7 : 30;
          const startTime = this.ganttScale() === 'week' ? 
            new Date(selectedDate.getTime() - ((selectedDate.getDay() === 0 ? 6 : selectedDate.getDay() - 1) * DAY)) :
            new Date(selectedDate.getFullYear(), selectedDate.getMonth(), 1);
            
          for (let i = 0; i < timeRange; i++) {
            const currentDay = new Date(startTime.getTime() + i * DAY);
            const dayAttendance = empAttendance.find(att => {
              const attDate = new Date(att.date);
              return attDate.toDateString() === currentDay.toDateString();
            });
            
            if (dayAttendance) {
              const dayStart = new Date(currentDay.getFullYear(), currentDay.getMonth(), currentDay.getDate());
              const dayEnd = new Date(dayStart.getTime() + DAY - 1);
              
              data.push({
                name: emp.name,
                value: [empIndex, dayStart.getTime(), dayEnd.getTime(), dayAttendance.status, dayAttendance.workHours],
                itemStyle: { color: statusColorMap[dayAttendance.status] || '#94a3b8' }
              });
            }
          }
        }
      });

      // 计算默认可视区域
      const total = categories.length;
      const visible = Math.min(total, 15);
      const defaultEndPercent = total > 0 ? Math.min(100, (visible / total) * 100) : 100;
      const todayTs = now.getTime();

      const option = {
        backgroundColor: 'transparent',
        tooltip: {
          trigger: 'item',
          formatter: (params: any) => {
            const v = params.value;
            const start = new Date(v[1]);
            const end = new Date(v[2]);
            const status = v[3];
            const workHours = v[4];
            
            if (this.ganttScale() === 'day') {
              return `员工：${params.name}<br/>状态：${status}<br/>工作时间：${start.toLocaleTimeString('zh-CN', {hour: '2-digit', minute: '2-digit'})} - ${end.toLocaleTimeString('zh-CN', {hour: '2-digit', minute: '2-digit'})}<br/>工时：${workHours || 0}小时`;
            } else {
              return `员工：${params.name}<br/>日期：${start.toLocaleDateString('zh-CN')}<br/>状态：${status}<br/>工时：${workHours || 0}小时`;
            }
          }
        },
        grid: { left: 120, right: 64, top: 30, bottom: 30 },
        xAxis: {
          type: 'time',
          min: xMin,
          max: xMax,
          splitNumber: xSplitNumber,
          axisLine: { lineStyle: { color: '#e5e7eb' } },
          axisLabel: { color: '#6b7280', formatter: xLabelFormatter },
          splitLine: { lineStyle: { color: '#f1f5f9' } }
        },
        yAxis: {
          type: 'category',
          data: categories,
          inverse: true,
          axisLabel: {
            color: '#374151',
            margin: 8,
            formatter: (val: string) => {
              const text = val.length > 12 ? val.slice(0, 12) + '…' : val;
              return text;
            }
          },
          axisTick: { show: false },
          axisLine: { lineStyle: { color: '#e5e7eb' } }
        },
      dataZoom: [
          { 
            type: 'slider', 
            yAxisIndex: 0, 
            orient: 'vertical', 
            right: 6, 
            width: 14, 
            start: 0, 
            end: defaultEndPercent, 
            zoomLock: false 
          },
          { 
            type: 'inside', 
            yAxisIndex: 0, 
            zoomOnMouseWheel: true, 
            moveOnMouseMove: true, 
            moveOnMouseWheel: true 
          }
        ],
        series: [
          {
            type: 'custom',
            renderItem: (params: any, api: any) => {
              const categoryIndex = api.value(0);
              const start = api.coord([api.value(1), categoryIndex]);
              const end = api.coord([api.value(2), categoryIndex]);
              const height = Math.max(api.size([0, 1])[1] * 0.6, 12);
              
              // 考勤状态条
              const rectShape = echarts.graphic.clipRectByRect({
                x: start[0],
                y: start[1] - height / 2,
                width: Math.max(end[0] - start[0], 2),
                height
              }, {
                x: params.coordSys.x,
                y: params.coordSys.y,
                width: params.coordSys.width,
                height: params.coordSys.height
              });

              // 今日标记线
              const isToday = this.ganttScale() === 'day' || 
                (api.value(1) <= todayTs && api.value(2) >= todayTs);
              
              const elements = [
                {
                  type: 'rect',
                  shape: rectShape,
                  style: {
                    ...api.style(),
                    stroke: isToday ? '#3b82f6' : 'transparent',
                    strokeWidth: isToday ? 2 : 0
                  }
                }
              ];

              return {
                type: 'group',
                children: elements
              };
            },
            encode: { x: [1, 2], y: 0 },
            data,
            itemStyle: { borderRadius: 6 },
            emphasis: { focus: 'self' }
          }
        ]
      };

      this.ganttChart.setOption(option, true);
      // 绑定点击事件，避免重复绑定
      this.ganttChart.off('click', this.onChartClick);
      this.ganttChart.on('click', this.onChartClick);
      this.ganttChart.resize();
    } catch (error) {
      console.error('甘特图更新失败:', error);
    }
  }
}
