import { 
  ChatMessage, 
  MessageBlock, 
  FetchMessagesRequest, 
  SendMessageRequest, 
  ChatConfig,
  ApiResponse,
  RealApiMessage,
  ApiMessageContent,
  MessagesResponse,
  FunctionName,
  ProjectInit,
  ScriptSummary,
  CharacterGeneration,
  SketchGeneration,
  ShotSketchGeneration,
  ShotVideoGeneration
} from "./types";
import { post } from "@/api/request";

// 空消息 默认展示
const EMPTY_MESSAGES: RealApiMessage[] = [
  {
    id: 1,
    role: 'assistant',
    content: JSON.stringify([{
      type: 'text',
      content: '🌟Welcome to MovieFlow 🎬✨\nTell me your idea～💡\nI am your AI assistant🤖, I can help you:\n🎭 Generate actor images\n📽️ Generate scene & shot sketches\n🎞️ Complete video creation\n\nLet\'s start our creative journey together!❤️'
    }]),
    created_at: new Date().toISOString(),
    function_name: undefined,
    custom_data: undefined,
    status: 'success',
    intent_type: 'function_call'
  }
];

// 用户积分不足消息
const NoEnoughCreditsMessageBlocks: MessageBlock[] = [
  {
    type: 'text',
    text: 'Insufficient credits.'
  },
  {
    type: 'link',
    text: 'Upgrade to continue.',
    url: '/pricing'
  }
];

/**
 * 类型守卫函数
 */
function isProjectInit(data: any): data is ProjectInit {
  return data && 'project_data' in data;
}

function isScriptSummary(data: any): data is ScriptSummary {
  return data && 'summary' in data;
}

function isCharacterGeneration(data: any): data is CharacterGeneration {
  return data && 'character_name' in data && 'image_path' in data && 'completed_count' in data && 'total_count' in data;
}

function isSketchGeneration(data: any): data is SketchGeneration {
  return data && 'sketch_name' in data && 'image_path' in data && 'completed_count' in data && 'total_count' in data;
}

function isShotSketchGeneration(data: any): data is ShotSketchGeneration {
  return data && 'shot_type' in data && 'atmosphere' in data && 'key_action' in data && 'url' in data && 'completed_count' in data && 'total_count' in data;
}

function isShotVideoGeneration(data: any): data is ShotVideoGeneration {
  return data && 'prompt_json' in data && 'urls' in data && 'completed_count' in data && 'total_count' in data;
}

function displayText(title: string, content: string, isLast: boolean = false) {
  return `${content ? `${title}: ${content}${isLast ? '' : '\n'}` : ''}`
}

/**
 * 系统消息转换为blocks数组
 */
function transformSystemMessage(
  functionName: FunctionName,
  content: string,
  customData: ProjectInit | ScriptSummary | CharacterGeneration | SketchGeneration | ShotSketchGeneration | ShotVideoGeneration
): MessageBlock[] {
  let blocks: MessageBlock[] = [];

  switch (functionName) {
    case 'create_project':
      if (isProjectInit(customData)) {
        blocks = [{ 
          type: 'text', 
          text: `🎬 According to your input "${customData.project_data.script}", I have completed the initialization of the project.\n${content}` 
        }];
      }
      break;

    case 'generate_script_summary':
      if (isScriptSummary(customData)) {
        blocks = [
          { type: 'text',  text: `🎬 I have completed the script summary generation.\n\n${customData.summary}\n\n${content}` }
        ];
      }
      break;

    case 'generate_character':
      if (isCharacterGeneration(customData)) {
        blocks = [{ 
          type: 'text', 
          text: `🎭 Actor "${customData.character_name}" is ready.` 
        }, { 
          type: 'image', 
          url: customData.image_path 
        }, {
          type: 'text', 
          text: 'The actor image is for reference only, and can be adjusted after the video is generated.'
        }, {
          type: 'progress',
          value: customData.completed_count,
          total: customData.total_count,
          label: `Completed ${customData.completed_count} actors, total ${customData.total_count} actors`
        }, {
          type: 'text',
          text: `\n${content}`
        }];
      }
      break;

    case 'generate_sketch':
      if (isSketchGeneration(customData)) {
        blocks = [{ 
          type: 'text', 
          text: `🎨 Scene "${customData.sketch_name}" reference image generated \n` 
        }, { 
          type: 'image', 
          url: customData.image_path 
        }, {
          type: 'text', 
          text: 'The scene image is for reference only, and can be adjusted after the video is generated.'
        }, {
          type: 'progress',
          value: customData.completed_count,
          total: customData.total_count,
          label: `Completed ${customData.completed_count} scenes, total ${customData.total_count} scenes`
        }, {
          type: 'text',
          text: `\n${content}`
        }];
      }
      break;

    case 'generate_shot_sketch':
      if (isShotSketchGeneration(customData)) {
        blocks = [{ 
          type: 'text', 
          text: `🎬 Storyboard static frame generation \n${displayText('Shot type', customData.shot_type)}${displayText('Atmosphere', customData.atmosphere)}${displayText('Key action', customData.key_action, true)}` 
        }, { 
          type: 'image', 
          url: customData.url 
        }, {
          type: 'text', 
          text: 'The storyboard static frame image is for reference only, and can be adjusted after the video is generated.'
        }, {
          type: 'progress',
          value: customData.completed_count,
          total: customData.total_count,
          label: `Completed ${customData.completed_count} storyboard static frames, total ${customData.total_count} storyboard static frames`
        }, {
          type: 'text',
          text: `\n${content}`
        }];
      }
      break;

    case 'generate_video':
      if (isShotVideoGeneration(customData)) {
        blocks.push({ 
          type: 'text', 
          text: `🎬 There are ${customData.urls.length} videos in this shot. \nCore atmosphere: ${customData.prompt_json.core_atmosphere}` 
        });
        customData.urls.forEach((url: string) => {
          blocks.push({ 
            type: 'video', 
            url: url 
          });
        });
        blocks.push({
          type: 'text', 
          text: 'You can edit the video on the editing line later.'
        }, {
          type: 'progress',
          value: customData.completed_count,
          total: customData.total_count,
          label: `Completed ${customData.completed_count} shots, total ${customData.total_count} shots`
        }, {
          type: 'text',
          text: `\n${content}`
        })
      }
      break;
  }

  return blocks;
}

/**
 * 将API响应转换为ChatMessage格式
 */
function transformMessage(apiMessage: RealApiMessage): ChatMessage {
  try {
    const { id, role, content, created_at, function_name, custom_data, status, intent_type } = apiMessage;
    let message: ChatMessage = {
      id: id ? id.toString() : Date.now().toString(),
      role: role,
      createdAt: new Date(created_at).getTime(),
      blocks: [],
      chatType: intent_type,
      status: status || 'success',
    };

    const errorMessage = custom_data?.error_message;
    if (errorMessage && errorMessage === 'no enough credits') {
      message.blocks = NoEnoughCreditsMessageBlocks;
    } else {
      if (role === 'assistant' || role === 'user') {
        try {
          const contentObj = JSON.parse(content);
          const contentArray = Array.isArray(contentObj) ? contentObj : [contentObj];
          contentArray.forEach((c: ApiMessageContent) => {
            if (c.type === "text") {
              message.blocks.push({ type: "text", text: c.content });
            } else if (c.type === "image") {
              message.blocks.push({ type: "image", url: c.content });
            } else if (c.type === "video") {
              message.blocks.push({ type: "video", url: c.content });
            } else if (c.type === "audio") {
              message.blocks.push({ type: "audio", url: c.content });
            } else if (c.type === "link") {
              message.blocks.push({ type: "link", text: c.content, url: c.url || '' });
            }
          });

          // todo: 需要确认是否需要添加applyButton
          // if (role === 'assistant' && function_name === 'modify_video_with_runway') {
          //   message.blocks.push({ type: "applyButton", text: "Apply" });
          // }
        } catch (error) {
          // 如果 JSON 解析失败，将整个 content 作为文本内容
          message.blocks.push({ type: "text", text: content });
        }
      } else if (role === 'system' && function_name && custom_data) {
        // 处理系统消息
        message.blocks = transformSystemMessage(function_name, content, custom_data);
      } else {
        message.blocks.push({ type: "text", text: content });
      }
    }

    // 如果没有有效的 blocks，至少添加一个文本块
    if (message.blocks.length === 0) {
      message.blocks.push({ type: "text", text: "No content" });
    }

    return message;
  } catch (error) {
    console.error("Failed to transform message format:", error, apiMessage);
    // 返回一个带有错误信息的消息
    return {
      id: new Date().getTime().toString(),
      role: apiMessage.role,
      createdAt: new Date(apiMessage.created_at).getTime(),
      blocks: [{ type: "text", text: "Message format error" }],
      chatType: 'chat',
      status: 'error',
    };
  }
}

/**
 * 获取消息列表
 */
export async function fetchMessages(
  config: ChatConfig,
  offset: number = 0,
  limit: number = 50
): Promise<{
  messages: ChatMessage[],
  hasMore: boolean,
  totalCount: number,
}> {
  const request: FetchMessagesRequest = {
    session_id: `project_${config.projectId}_user_${config.userId}`,
    limit,
    offset,
  };

  try {
    console.log('Send history message request:', request);
    const response = await post<ApiResponse<MessagesResponse>>("/intelligent/history", request);
    console.log('Receive history message response:', response);

    // 确保 response.data 和 messages 存在
    if (!response.data || !response.data.messages) {
      console.error('History message response format error:', response);
      return {
        messages: [],
        hasMore: false,
        totalCount: 0
      };
    }

    // 转换消息并按时间排序
    if (response.data.messages.length === 0) {
      return {
        messages: EMPTY_MESSAGES.map(transformMessage),
        hasMore: false,
        totalCount: 0
      };
    }
    return {
      messages: response.data.messages
      .map(transformMessage)
      .sort((a, b) => Number(a.id) - Number(b.id)),
      hasMore: response.data.has_more,
      totalCount: response.data.total_count
    };
  } catch (error) {
    console.error("Failed to get message history:", error);
    throw error;
  }
}

/**
 * 发送新消息
 */
export async function sendMessage(
  blocks: MessageBlock[],
  config: ChatConfig,
  videoId?: string
): Promise<void> {
  // 提取文本、图片和视频
  const textBlocks = blocks.filter(b => b.type === "text");
  const imageBlocks = blocks.filter(b => b.type === "image");
  const videoBlocks = blocks.filter(b => b.type === "video");
  
  const request: SendMessageRequest = {
    session_id: `project_${config.projectId}_user_${config.userId}`,
    user_input: textBlocks.map(b => (b as { text: string }).text).join("\n"),
    project_id: config.projectId,
    user_id: config.userId.toString(),
  };

  // 如果有图片，添加第一张图片的URL
  if (imageBlocks.length > 0) {
    request.image_url = (imageBlocks[0] as { url: string }).url;
  }

  // 如果有视频，添加视频URL
  if (videoBlocks.length > 0) {
    request.video_url = (videoBlocks[0] as { url: string }).url;
  }

  // 如果有视频ID，添加到请求中
  if (videoId) {
    request.video_id = videoId;
  }

  try {
    console.log('Send message request:', request);
    await post<ApiResponse<RealApiMessage>>("/intelligent/chat", request);
  } catch (error) {
    console.error("Send message failed:", error);
    throw error;
  }
}

/**
 * 重试发送消息
 */
export async function retryMessage(
  messageId: string,
  config: ChatConfig
): Promise<void> {
  // TODO: 实现实际的重试逻辑，可能需要保存原始消息内容
  // 这里简单重用发送消息的接口
  return sendMessage([{ type: "text", text: "Retry message" }], config);
}