import { http } from './http';

export type MaterialType = 'image' | 'video' | 'audio';
export type ProcessingStatus = 'pending' | 'processing' | 'completed' | 'failed';
export type TranslationLanguage = 'en' | 'zh' | 'ja' | 'ko' | 'es' | 'fr' | 'de' | 'ar' | 'pt' | 'ru';

export interface MaterialProcessJob {
  id: string;
  type: 'image_to_image' | 'image_to_video' | 'video_translation' | 'video_dubbing';
  status: ProcessingStatus;
  inputUrl: string;
  outputUrl?: string;
  params: Record<string, any>;
  progress: number;
  createdAt: string;
  updatedAt: string;
  error?: string;
}

export interface ImageToImageParams {
  prompt?: string;
  style?: 'realistic' | 'artistic' | 'anime' | '3d' | 'sketch';
  strength?: number;
  seed?: number;
}

export interface ImageToVideoParams {
  duration: number;
  fps?: number;
  motion?: 'zoom' | 'pan' | 'rotate' | 'dynamic';
  prompt?: string;
}

export interface VideoTranslationParams {
  sourceLanguage: string;
  targetLanguage: TranslationLanguage;
  voiceType?: 'male' | 'female' | 'neutral';
  preserveBackgroundAudio?: boolean;
}

export interface VideoDubbingParams {
  targetLanguage: TranslationLanguage;
  voiceType?: 'male' | 'female' | 'neutral';
  syncLips?: boolean;
}

export interface IMaterialProcessingDataSource {
  imageToImage(inputUrl: string, params: ImageToImageParams): Promise<MaterialProcessJob>;
  imageToVideo(inputUrl: string, params: ImageToVideoParams): Promise<MaterialProcessJob>;
  translateVideo(inputUrl: string, params: VideoTranslationParams): Promise<MaterialProcessJob>;
  dubVideo(inputUrl: string, params: VideoDubbingParams): Promise<MaterialProcessJob>;
  getJobStatus(jobId: string): Promise<MaterialProcessJob>;
  getJobs(): Promise<MaterialProcessJob[]>;
  cancelJob(jobId: string): Promise<void>;
}

const TRANSLATION_LANGUAGES: Record<TranslationLanguage, string> = {
  en: 'English',
  zh: '中文',
  ja: '日本語',
  ko: '한국어',
  es: 'Español',
  fr: 'Français',
  de: 'Deutsch',
  ar: 'العربية',
  pt: 'Português',
  ru: 'Русский',
};

const STYLE_OPTIONS = [
  { value: 'realistic', label: '写实风格' },
  { value: 'artistic', label: '艺术风格' },
  { value: 'anime', label: '动漫风格' },
  { value: '3d', label: '3D渲染' },
  { value: 'sketch', label: '素描风格' },
];

const MOTION_OPTIONS = [
  { value: 'zoom', label: '缩放' },
  { value: 'pan', label: '平移' },
  { value: 'rotate', label: '旋转' },
  { value: 'dynamic', label: '动态' },
];

class MockMaterialProcessingDataSource implements IMaterialProcessingDataSource {
  private jobs: MaterialProcessJob[] = [];
  private jobCounter = 0;

  private generateId(): string {
    return `MPJ-${Date.now()}-${++this.jobCounter}`;
  }

  private async simulateProcessing(job: MaterialProcessJob, duration: number = 5000): Promise<void> {
    const steps = 10;
    const stepDuration = duration / steps;
    
    for (let i = 1; i <= steps; i++) {
      await new Promise(resolve => setTimeout(resolve, stepDuration));
      job.progress = i * 10;
      job.updatedAt = new Date().toISOString();
      
      if (i === steps) {
        job.status = 'completed';
        job.outputUrl = `https://example.com/output/${job.id}.${job.type === 'image_to_image' ? 'jpg' : 'mp4'}`;
      }
    }
  }

  async imageToImage(inputUrl: string, params: ImageToImageParams): Promise<MaterialProcessJob> {
    const job: MaterialProcessJob = {
      id: this.generateId(),
      type: 'image_to_image',
      status: 'processing',
      inputUrl,
      params,
      progress: 0,
      createdAt: new Date().toISOString(),
      updatedAt: new Date().toISOString(),
    };
    
    this.jobs.unshift(job);
    this.simulateProcessing(job, 3000);
    
    return job;
  }

  async imageToVideo(inputUrl: string, params: ImageToVideoParams): Promise<MaterialProcessJob> {
    const job: MaterialProcessJob = {
      id: this.generateId(),
      type: 'image_to_video',
      status: 'processing',
      inputUrl,
      params,
      progress: 0,
      createdAt: new Date().toISOString(),
      updatedAt: new Date().toISOString(),
    };
    
    this.jobs.unshift(job);
    this.simulateProcessing(job, 8000);
    
    return job;
  }

  async translateVideo(inputUrl: string, params: VideoTranslationParams): Promise<MaterialProcessJob> {
    const job: MaterialProcessJob = {
      id: this.generateId(),
      type: 'video_translation',
      status: 'processing',
      inputUrl,
      params,
      progress: 0,
      createdAt: new Date().toISOString(),
      updatedAt: new Date().toISOString(),
    };
    
    this.jobs.unshift(job);
    this.simulateProcessing(job, 10000);
    
    return job;
  }

  async dubVideo(inputUrl: string, params: VideoDubbingParams): Promise<MaterialProcessJob> {
    const job: MaterialProcessJob = {
      id: this.generateId(),
      type: 'video_dubbing',
      status: 'processing',
      inputUrl,
      params,
      progress: 0,
      createdAt: new Date().toISOString(),
      updatedAt: new Date().toISOString(),
    };
    
    this.jobs.unshift(job);
    this.simulateProcessing(job, 12000);
    
    return job;
  }

  async getJobStatus(jobId: string): Promise<MaterialProcessJob> {
    const job = this.jobs.find(j => j.id === jobId);
    if (!job) {
      throw new Error('Job not found');
    }
    return job;
  }

  async getJobs(): Promise<MaterialProcessJob[]> {
    return this.jobs;
  }

  async cancelJob(jobId: string): Promise<void> {
    const job = this.jobs.find(j => j.id === jobId);
    if (job && job.status === 'processing') {
      job.status = 'failed';
      job.error = 'Cancelled by user';
      job.updatedAt = new Date().toISOString();
    }
  }
}

class ApiMaterialProcessingDataSource implements IMaterialProcessingDataSource {
  private baseUrl = '/api/v1/material-processing';

  async imageToImage(inputUrl: string, params: ImageToImageParams): Promise<MaterialProcessJob> {
    const response = await http.post(`${this.baseUrl}/image-to-image`, { inputUrl, params });
    return response.data;
  }

  async imageToVideo(inputUrl: string, params: ImageToVideoParams): Promise<MaterialProcessJob> {
    const response = await http.post(`${this.baseUrl}/image-to-video`, { inputUrl, params });
    return response.data;
  }

  async translateVideo(inputUrl: string, params: VideoTranslationParams): Promise<MaterialProcessJob> {
    const response = await http.post(`${this.baseUrl}/video-translation`, { inputUrl, params });
    return response.data;
  }

  async dubVideo(inputUrl: string, params: VideoDubbingParams): Promise<MaterialProcessJob> {
    const response = await http.post(`${this.baseUrl}/video-dubbing`, { inputUrl, params });
    return response.data;
  }

  async getJobStatus(jobId: string): Promise<MaterialProcessJob> {
    const response = await http.get(`${this.baseUrl}/jobs/${jobId}`);
    return response.data;
  }

  async getJobs(): Promise<MaterialProcessJob[]> {
    const response = await http.get(`${this.baseUrl}/jobs`);
    return response.data;
  }

  async cancelJob(jobId: string): Promise<void> {
    await http.post(`${this.baseUrl}/jobs/${jobId}/cancel`);
  }
}

const useMock = process.env.NODE_ENV === 'development' || process.env.REACT_APP_USE_MOCK === 'true';
export const materialProcessingDataSource: IMaterialProcessingDataSource = useMock
  ? new MockMaterialProcessingDataSource()
  : new ApiMaterialProcessingDataSource();

export { TRANSLATION_LANGUAGES, STYLE_OPTIONS, MOTION_OPTIONS };
