import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable, BehaviorSubject, throwError } from 'rxjs';
import { catchError, map } from 'rxjs/operators';

export interface UploadedFile {
  id: string;
  name: string;
  url: string;
  size?: number;
  type?: string;
  preview?: string;
}

export interface ColorAnalysisResult {
  colors: Array<{
    hex: string;
    rgb: { r: number; g: number; b: number };
    percentage: number;
  }>;
  originalImage: string;
  mosaicImage: string;
  reportPath: string;
}

export interface AnalysisProgress {
  stage: 'preparing' | 'processing' | 'extracting' | 'generating' | 'completed' | 'error';
  message: string;
  progress: number;
}

@Injectable({
  providedIn: 'root'
})
export class ColorAnalysisService {
  private readonly API_BASE = '/api/color-analysis';
  private analysisProgress$ = new BehaviorSubject<AnalysisProgress>({
    stage: 'preparing',
    message: '准备分析...',
    progress: 0
  });

  constructor(private http: HttpClient) {}

  /**
   * 获取分析进度
   */
  getAnalysisProgress(): Observable<AnalysisProgress> {
    return this.analysisProgress$.asObservable();
  }

  /**
   * 分析图片颜色
   * @param imageFile 图片文件
   * @param options 分析选项
   */
  analyzeImageColors(imageFile: File, options?: {
    mosaicSize?: number;
    maxColors?: number;
  }): Observable<ColorAnalysisResult> {
    const formData = new FormData();
    formData.append('image', imageFile);
    
    if (options?.mosaicSize) {
      formData.append('mosaicSize', options.mosaicSize.toString());
    }
    if (options?.maxColors) {
      formData.append('maxColors', options.maxColors.toString());
    }

    return this.http.post<any>(`${this.API_BASE}/analyze`, formData).pipe(
      map((response: any) => {
        if (response && response.success) {
          return this.parseAnalysisResult(response.data);
        }
        throw new Error('分析结果无效');
      }),
      catchError(error => {
        console.error('颜色分析失败:', error);
        return throwError(() => new Error('颜色分析服务暂时不可用'));
      })
    );
  }

  /**
   * 分析上传的图片文件
   * @param file 上传的文件信息
   */
  analyzeImage(file: UploadedFile): Observable<ColorAnalysisResult> {
    return this.http.post<any>('/api/color-analysis/analyze', {
      fileId: file.id,
      fileName: file.name,
      fileUrl: file.url
    }).pipe(
      map((response: any) => {
        if (response && response.success) {
          return response.data as ColorAnalysisResult;
        }
        throw new Error('分析结果无效');
      }),
      catchError(error => {
        console.error('颜色分析失败:', error);
        return throwError(() => new Error('颜色分析服务暂时不可用'));
      })
    );
  }

  /**
   * 获取分析报告
   * @param reportId 报告ID
   */
  getAnalysisReport(reportId: string): Observable<string> {
    return this.http.get(`${this.API_BASE}/report/${reportId}`, {
      responseType: 'text'
    });
  }

  /**
   * 批量分析多个图片
   * @param imageFiles 图片文件数组
   */
  analyzeBatchImages(imageFiles: File[]): Observable<ColorAnalysisResult[]> {
    this.updateProgress('preparing', '准备批量分析...', 0);

    const formData = new FormData();
    imageFiles.forEach((file, index) => {
      formData.append(`images`, file);
    });

    return this.http.post<any>(`${this.API_BASE}/analyze-batch`, formData).pipe(
      map(response => {
        this.updateProgress('completed', '批量分析完成', 100);
        return response.results.map((result: any) => this.parseAnalysisResult(result));
      }),
      catchError(error => {
        this.updateProgress('error', '批量分析失败: ' + (error.message || '未知错误'), 0);
        return throwError(() => error);
      })
    );
  }

  /**
   * 检查color-get服务状态
   */
  checkServiceStatus(): Observable<boolean> {
    return this.http.get<{ status: string }>(`${this.API_BASE}/status`).pipe(
      map(response => response.status === 'ready'),
      catchError(() => throwError(() => new Error('颜色分析服务不可用')))
    );
  }

  /**
   * 更新分析进度
   */
  private updateProgress(stage: AnalysisProgress['stage'], message: string, progress: number): void {
    this.analysisProgress$.next({ stage, message, progress });
  }

  /**
   * 解析分析结果
   */
  private parseAnalysisResult(data: any): ColorAnalysisResult {
    return {
      colors: data.colors || [],
      originalImage: data.originalImage || '',
      mosaicImage: data.mosaicImage || '',
      reportPath: data.reportPath || ''
    };
  }

  /**
   * 模拟color-get分析过程（用于开发测试）
   */
  simulateAnalysis(imageFile: File): Observable<ColorAnalysisResult> {
    return new Observable(observer => {
      // 模拟分析步骤
      const steps = [
        { stage: 'preparing' as const, message: '准备分析图片...', progress: 10 },
        { stage: 'processing' as const, message: '生成马赛克图片...', progress: 30 },
        { stage: 'extracting' as const, message: '提取颜色信息...', progress: 60 },
        { stage: 'generating' as const, message: '生成分析报告...', progress: 90 },
      ];

      let currentStep = 0;
      const interval = setInterval(() => {
        if (currentStep < steps.length) {
          const step = steps[currentStep];
          this.updateProgress(step.stage, step.message, step.progress);
          currentStep++;
        } else {
          clearInterval(interval);
          
          // 模拟分析结果
          const mockResult: ColorAnalysisResult = {
            colors: [
              { hex: '#FF6B6B', rgb: { r: 255, g: 107, b: 107 }, percentage: 25.5 },
              { hex: '#4ECDC4', rgb: { r: 78, g: 205, b: 196 }, percentage: 18.3 },
              { hex: '#45B7D1', rgb: { r: 69, g: 183, b: 209 }, percentage: 15.7 },
              { hex: '#96CEB4', rgb: { r: 150, g: 206, b: 180 }, percentage: 12.1 },
              { hex: '#FFEAA7', rgb: { r: 255, g: 234, b: 167 }, percentage: 10.8 },
              { hex: '#DDA0DD', rgb: { r: 221, g: 160, b: 221 }, percentage: 8.9 },
              { hex: '#98D8C8', rgb: { r: 152, g: 216, b: 200 }, percentage: 8.7 }
            ],
            originalImage: URL.createObjectURL(imageFile),
            mosaicImage: URL.createObjectURL(imageFile), // 在实际应用中这里应该是处理后的图片
            reportPath: '/mock-report.html'
          };

          this.updateProgress('completed', '分析完成', 100);
          observer.next(mockResult);
          observer.complete();
        }
      }, 800);
    });
  }
}