import { Injectable } from '@angular/core';
import { completionJSON, FmodeChatCompletion } from 'fmode-ng/core/agent/chat/completion';
import { Observable } from 'rxjs';

// 使用的AI模型
export const ProjectAIModel = 'fmode-1.6-cn';

/**
 * AI服务
 * 提供设计方案生成、项目复盘、图片识别等AI能力
 */
@Injectable({
  providedIn: 'root'
})
export class ProjectAIService {
  constructor() {}

  /**
   * 生成设计方案
   * @param requirements 需求信息
   * @param options 生成选项
   * @returns 设计方案
   */
  async generateDesignSolution(
    requirements: {
      spaces: Array<{
        name: string;
        area: number;
        description: string;
      }>;
      stylePreference: string;
      colorScheme: {
        atmosphere: string;
      };
      budget: {
        min: number;
        max: number;
      };
      specialRequirements?: string;
    },
    options?: {
      onProgress?: (content: string) => void;
      images?: string[]; // 参考图片URL
    }
  ): Promise<any> {
    // 构建提示词
    const prompt = this.buildDesignPrompt(requirements);

    // 定义输出JSON结构
    const outputSchema = `{
  "spaces": [
    {
      "name": "空间名称",
      "styleDescription": "设计风格描述，突出特点和氛围营造",
      "colorPalette": ["#FFFFFF", "#主色", "#辅色", "#点缀色"],
      "materials": ["材质1", "材质2", "材质3"],
      "furnitureRecommendations": ["家具1", "家具2", "家具3"]
    }
  ],
  "estimatedCost": 150000,
  "timeline": "项目周期说明，包括设计、施工、软装等阶段"
}`;

    try {
      // 使用completionJSON生成结构化数据
      const result = await completionJSON(
        prompt,
        outputSchema,
        (content: string) => {
          options?.onProgress?.(content);
        },
        3, // 最大重试次数
        {
          model: ProjectAIModel,
          vision: options?.images && options.images.length > 0,
          images: options?.images
        }
      );

      return {
        generated: true,
        content: '基于您的需求，我们为您设计了以下方案...',
        ...result
      };
    } catch (error: any) {
      console.error('生成设计方案失败:', error);
      throw new Error('生成设计方案失败: ' + (error?.message || '未知错误'));
    }
  }

  /**
   * 生成项目复盘
   * @param projectData 项目数据
   * @param options 生成选项
   * @returns 复盘报告
   */
  async generateProjectRetrospective(
    projectData: {
      title: string;
      type: string;
      duration?: number;
      customerRating?: number;
      challenges?: string[];
    },
    options?: {
      onProgress?: (content: string) => void;
    }
  ): Promise<any> {
    const prompt = this.buildRetrospectivePrompt(projectData);

    const outputSchema = `{
  "summary": "项目整体总结，1-2句话概括",
  "highlights": ["亮点1", "亮点2", "亮点3"],
  "challenges": ["挑战1", "挑战2"],
  "lessons": ["教训1", "教训2", "教训3"],
  "recommendations": ["建议1", "建议2", "建议3"]
}`;

    try {
      const result = await completionJSON(
        prompt,
        outputSchema,
        (content: string) => {
          options?.onProgress?.(content);
        },
        2,
        {
          model: ProjectAIModel
        }
      );

      return {
        generated: true,
        ...result
      };
    } catch (error: any) {
      console.error('生成项目复盘失败:', error);
      throw new Error('生成项目复盘失败: ' + (error?.message || '未知错误'));
    }
  }

  /**
   * 识别图片内容（OCR + 理解）
   * @param images 图片URL数组
   * @param prompt 识别提示词
   * @param options 识别选项
   * @returns 识别结果
   */
  async recognizeImages(
    images: string[],
    prompt: string,
    options?: {
      onProgress?: (content: string) => void;
      outputSchema?: string;
    }
  ): Promise<any> {
    const defaultSchema = `{
  "description": "图片内容描述",
  "keywords": ["关键词1", "关键词2"],
  "details": {}
}`;

    try {
      const result = await completionJSON(
        prompt,
        options?.outputSchema || defaultSchema,
        (content: string) => {
          options?.onProgress?.(content);
        },
        2,
        {
          model: ProjectAIModel,
          vision: true,
          images: images
        }
      );

      return result;
    } catch (error: any) {
      console.error('图片识别失败:', error);
      throw new Error('图片识别失败: ' + (error?.message || '未知错误'));
    }
  }

  /**
   * 流式生成文本回答
   * @param prompt 提示词
   * @param options 生成选项
   * @returns Observable流
   */
  streamCompletion(
    prompt: string,
    options?: {
      model?: string;
      temperature?: number;
    }
  ): Observable<any> {
    const messageList = [
      {
        role: 'user',
        content: prompt
      }
    ];

    const completion = new FmodeChatCompletion(messageList, {
      model: options?.model || ProjectAIModel
    });

    return completion.sendCompletion({
      isDirect: true
    });
  }

  /**
   * 构建设计方案提示词
   */
  private buildDesignPrompt(requirements: any): string {
    let prompt = `作为专业的室内设计师，请根据以下客户需求生成详细的设计方案：\n\n`;

    // 空间信息
    prompt += `【空间需求】\n`;
    requirements.spaces.forEach((space: any, index: number) => {
      prompt += `${index + 1}. ${space.name} (${space.area}㎡)\n`;
      if (space.description) {
        prompt += `   说明: ${space.description}\n`;
      }
    });
    prompt += `\n`;

    // 风格偏好
    if (requirements.stylePreference) {
      prompt += `【风格偏好】\n${requirements.stylePreference}\n\n`;
    }

    // 色彩氛围
    if (requirements.colorScheme?.atmosphere) {
      prompt += `【色彩氛围】\n${requirements.colorScheme.atmosphere}\n\n`;
    }

    // 预算范围
    if (requirements.budget?.max > 0) {
      prompt += `【预算范围】\n${requirements.budget.min / 10000}-${requirements.budget.max / 10000}万元\n\n`;
    }

    // 特殊需求
    if (requirements.specialRequirements) {
      prompt += `【特殊需求】\n${requirements.specialRequirements}\n\n`;
    }

    prompt += `请为每个空间生成：\n`;
    prompt += `1. 设计风格描述（强调氛围营造和功能性）\n`;
    prompt += `2. 色彩搭配方案（提供4种色值的HEX代码）\n`;
    prompt += `3. 材质选择建议（3-4种主要材质）\n`;
    prompt += `4. 家具推荐清单（3-5件核心家具）\n`;
    prompt += `5. 整体预算估算和项目周期\n\n`;

    prompt += `要求：\n`;
    prompt += `- 设计方案要专业、可执行\n`;
    prompt += `- 色彩搭配要和谐、符合氛围要求\n`;
    prompt += `- 材质和家具推荐要考虑预算范围\n`;
    prompt += `- 项目周期要合理、细分到各阶段\n`;

    return prompt;
  }

  /**
   * 构建项目复盘提示词
   */
  private buildRetrospectivePrompt(projectData: any): string {
    let prompt = `作为项目经理，请对以下项目进行复盘总结：\n\n`;

    prompt += `【项目信息】\n`;
    prompt += `项目名称: ${projectData.title}\n`;
    prompt += `项目类型: ${projectData.type}\n`;

    if (projectData.duration) {
      prompt += `项目周期: ${projectData.duration}天\n`;
    }

    if (projectData.customerRating) {
      prompt += `客户评分: ${projectData.customerRating}星\n`;
    }

    if (projectData.challenges && projectData.challenges.length > 0) {
      prompt += `\n【遇到的挑战】\n`;
      projectData.challenges.forEach((challenge: string, index: number) => {
        prompt += `${index + 1}. ${challenge}\n`;
      });
    }

    prompt += `\n请从以下几个方面进行总结：\n`;
    prompt += `1. 项目亮点和成功经验（3-4条）\n`;
    prompt += `2. 遇到的挑战和问题（2-3条）\n`;
    prompt += `3. 经验教训和改进点（3-5条）\n`;
    prompt += `4. 对未来项目的建议（3-4条）\n\n`;

    prompt += `要求：\n`;
    prompt += `- 总结要客观、实用\n`;
    prompt += `- 亮点要具体、可复制\n`;
    prompt += `- 教训要深刻、有启发性\n`;
    prompt += `- 建议要可行、有价值\n`;

    return prompt;
  }

  /**
   * 提取色彩信息（从参考图片）
   * @param imageUrls 图片URL数组
   * @returns 色彩信息
   */
  async extractColors(imageUrls: string[]): Promise<any> {
    const prompt = `请分析图片中的主要色彩，提取4种核心色值（主色、辅色、点缀色、中性色），并判断整体的色彩氛围（温馨/高级/简约/时尚）。

输出要求：
- 色值使用HEX格式（如#FFFFFF）
- 氛围描述要准确、专业
- 说明色彩的应用场景`;

    const outputSchema = `{
  "colors": [
    {"hex": "#FFFFFF", "name": "主色", "usage": "墙面、大面积使用"},
    {"hex": "#E8E8E8", "name": "辅色", "usage": "家具、装饰"},
    {"hex": "#4A4A4A", "name": "点缀色", "usage": "配饰、细节"},
    {"hex": "#F5F5F5", "name": "中性色", "usage": "过渡、平衡"}
  ],
  "atmosphere": "温馨",
  "description": "整体色彩氛围描述"
}`;

    return await this.recognizeImages(imageUrls, prompt, { outputSchema });
  }

  /**
   * OCR识别支付凭证
   * @param imageUrl 凭证图片URL
   * @returns 识别结果
   */
  async recognizePaymentVoucher(imageUrl: string): Promise<any> {
    const prompt = `请识别图片中的支付凭证信息，提取以下内容：
1. 支付金额
2. 支付时间
3. 支付方式（银行转账/支付宝/微信等）
4. 付款人信息（如有）
5. 收款人信息（如有）

注意：
- 金额要精确到分
- 时间格式：YYYY-MM-DD HH:mm:ss
- 如果信息不清晰，请标注为"未识别"`;

    const outputSchema = `{
  "amount": 50000.00,
  "paymentTime": "2025-01-15 14:30:00",
  "paymentMethod": "银行转账",
  "payer": "张三",
  "payee": "映三色设计",
  "confidence": 0.95
}`;

    return await this.recognizeImages([imageUrl], prompt, { outputSchema });
  }
}
