import { Component, EventEmitter, Input, Output, ViewChild, ElementRef } from '@angular/core';
import { CommonModule } from '@angular/common';
import { NovaStorage, NovaFile } from 'fmode-ng/core';

export interface UploadResult {
  success: boolean;
  file?: NovaFile;
  url?: string;
  error?: string;
}

@Component({
  selector: 'app-upload-component',
  standalone: true,
  imports: [CommonModule],
  templateUrl: './upload.component.html',
  styleUrls: ['./upload.component.scss']
})
export class UploadComponent {
  @Input() accept: string = '*/*'; // 接受的文件类型
  @Input() multiple: boolean = false; // 是否支持多文件上传
  @Input() maxSize: number = 10; // 最大文件大小(MB)
  @Input() allowedTypes: string[] = []; // 允许的文件类型
  @Input() prefixKey: string = ''; // 文件存储前缀
  @Input() disabled: boolean = false; // 是否禁用
  @Input() showPreview: boolean = false; // 是否显示预览
  @Input() compressImages: boolean = true; // 是否压缩图片

  @Output() fileSelected = new EventEmitter<File[]>(); // 文件选择事件
  @Output() uploadStart = new EventEmitter<File[]>(); // 上传开始事件
  @Output() uploadProgressEvent = new EventEmitter<{ completed: number; total: number; currentFile: string }>(); // 上传进度事件
  @Output() uploadComplete = new EventEmitter<UploadResult[]>(); // 上传完成事件
  @Output() uploadError = new EventEmitter<string>(); // 上传错误事件

  @ViewChild('fileInput') fileInput!: ElementRef<HTMLInputElement>;

  isUploading: boolean = false;
  uploadProgress: number = 0;
  uploadedFiles: UploadResult[] = [];
  dragOver: boolean = false;
  private storage: NovaStorage | null = null;

  constructor() {
    this.initStorage();
  }

  // 初始化 NovaStorage
  private async initStorage(): Promise<void> {
    try {
      const cid = localStorage.getItem('company') || 'cDL6R1hgSi';
      this.storage = await NovaStorage.withCid(cid);
      console.log('✅ NovaStorage 初始化成功, cid:', cid);
    } catch (error) {
      console.error('❌ NovaStorage 初始化失败:', error);
    }
  }

  /**
   * 触发文件选择
   */
  triggerFileSelect(): void {
    if (!this.disabled) {
      this.fileInput.nativeElement.click();
    }
  }

  /**
   * 处理文件选择
   */
  onFileSelect(event: Event): void {
    const target = event.target as HTMLInputElement;
    const files = Array.from(target.files || []);

    if (files.length > 0) {
      this.handleFiles(files);
    }

    // 清空input值，允许重复选择同一文件
    target.value = '';
  }

  /**
   * 处理拖拽进入
   */
  onDragOver(event: DragEvent): void {
    event.preventDefault();
    event.stopPropagation();

    if (!this.disabled) {
      this.dragOver = true;
    }
  }

  /**
   * 处理拖拽离开
   */
  onDragLeave(event: DragEvent): void {
    event.preventDefault();
    event.stopPropagation();
    this.dragOver = false;
  }

  /**
   * 处理文件拖拽放下
   */
  onDrop(event: DragEvent): void {
    event.preventDefault();
    event.stopPropagation();
    this.dragOver = false;

    if (this.disabled) {
      return;
    }

    const files = Array.from(event.dataTransfer?.files || []);

    if (files.length > 0) {
      this.handleFiles(files);
    }
  }

  /**
   * 处理文件（验证并上传）
   */
  private async handleFiles(files: File[]): Promise<void> {
    // 验证文件
    const validationError = this.validateFiles(files);
    if (validationError) {
      this.uploadError.emit(validationError);
      return;
    }

    this.fileSelected.emit(files);

    // 开始上传
    await this.uploadFiles(files);
  }

  /**
   * 验证文件
   */
  private validateFiles(files: File[]): string | null {
    if (files.length === 0) {
      return '请选择文件';
    }

    // 检查文件类型
    if (this.allowedTypes.length > 0) {
      const invalidFiles = files.filter(file =>
        !this.validateFileType(file, this.allowedTypes)
      );

      if (invalidFiles.length > 0) {
        return `不支持的文件类型: ${invalidFiles.map(f => f.name).join(', ')}`;
      }
    }

    // 检查文件大小
    const oversizedFiles = files.filter(file =>
      !this.validateFileSize(file, this.maxSize)
    );

    if (oversizedFiles.length > 0) {
      return `文件大小超过限制 (${this.maxSize}MB): ${oversizedFiles.map(f => f.name).join(', ')}`;
    }

    return null;
  }

  /**
   * 验证文件类型
   */
  private validateFileType(file: File, allowedTypes: string[]): boolean {
    return allowedTypes.some(type => file.type.includes(type));
  }

  /**
   * 验证文件大小
   */
  private validateFileSize(file: File, maxSizeInMB: number): boolean {
    const maxSizeInBytes = maxSizeInMB * 1024 * 1024;
    return file.size <= maxSizeInBytes;
  }

  /**
   * 上传文件
   */
  private async uploadFiles(files: File[]): Promise<void> {
    if (!this.storage) {
      this.uploadError.emit('存储服务未初始化');
      return;
    }

    this.isUploading = true;
    this.uploadProgress = 0;
    this.uploadedFiles = [];

    this.uploadStart.emit(files);

    try {
      const results: UploadResult[] = [];

      for (let i = 0; i < files.length; i++) {
        const file = files[i];

        // 更新进度
        const progress = ((i + 1) / files.length) * 100;
        this.uploadProgress = progress;
        this.uploadProgressEvent.emit({
          completed: i + 1,
          total: files.length,
          currentFile: file.name
        });

        try {
          // 使用 NovaStorage 上传文件
          const uploaded: NovaFile = await this.storage.upload(file, {
            prefixKey: this.prefixKey,
            onProgress: (p) => {
              const fileProgress = (i / files.length) * 100 + (p.total.percent / files.length);
              this.uploadProgress = fileProgress;
              this.uploadProgressEvent.emit({
                completed: i,
                total: files.length,
                currentFile: file.name
              });
            }
          });

          const result: UploadResult = {
            success: true,
            file: uploaded,
            url: uploaded.url
          };

          results.push(result);
          console.log('✅ 文件上传成功:', uploaded.key, uploaded.url);

        } catch (error) {
          const result: UploadResult = {
            success: false,
            error: error instanceof Error ? error.message : '上传失败'
          };
          results.push(result);
          console.error('❌ 文件上传失败:', file.name, error);
        }
      }

      this.uploadedFiles = results;
      this.uploadComplete.emit(results);

      // 检查是否有失败的上传
      const failedUploads = results.filter(r => !r.success);
      if (failedUploads.length > 0) {
        const errorMessages = failedUploads.map(r => r.error).filter(Boolean);
        this.uploadError.emit(`部分文件上传失败: ${errorMessages.join(', ')}`);
      }

    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : '上传过程中发生错误';
      this.uploadError.emit(errorMessage);
    } finally {
      this.isUploading = false;
      this.uploadProgress = 0;
    }
  }

  /**
   * 删除已上传的文件
   */
  removeUploadedFile(index: number): void {
    this.uploadedFiles.splice(index, 1);
  }

  /**
   * 格式化文件大小
   */
  formatFileSize(bytes: number): string {
    if (bytes === 0) return '0 Bytes';

    const k = 1024;
    const sizes = ['Bytes', 'KB', 'MB', 'GB'];
    const i = Math.floor(Math.log(bytes) / Math.log(k));

    return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
  }

  /**
   * 获取文件扩展名
   */
  getFileExtension(filename: string): string {
    return filename.split('.').pop()?.toLowerCase() || '';
  }

  /**
   * 检查是否为图片文件
   */
  isImageFile(file: File): boolean {
    return file.type.startsWith('image/');
  }

  /**
   * 生成预览URL
   */
  generatePreviewUrl(file: File): string {
    if (this.isImageFile(file)) {
      return URL.createObjectURL(file);
    }
    return '';
  }

  /**
   * 清空上传结果
   */
  clearResults(): void {
    this.uploadedFiles = [];
    this.uploadProgress = 0;
  }

  /**
   * 重置组件状态
   */
  reset(): void {
    this.isUploading = false;
    this.uploadProgress = 0;
    this.uploadedFiles = [];
    this.dragOver = false;
    if (this.fileInput) {
      this.fileInput.nativeElement.value = '';
    }
  }
}