import type { MessageProps } from "datastellar-chatui";
import type { ReactNode } from "react";
import type { CTX, MsgProps } from "./CTX";
import type { FileItem } from './INPUTPROPS';
import type { CautionItem, ToolBarType } from './CONFIG';
import type { PreFeedBack, PreSpeechToText, PreVoice } from "./REQUEST";
import type { CustomOption } from './UI';

export type TSource = Array<string | ReactNode>
export type TQuick = Array<{ name: string }>

export interface TMsgItem extends MsgProps {
  content: {
    data: any
    source?: TSource
    quickReplies?: TQuick
  }
}

export interface ChatResponse {
  [key: string]: any
  // 显示类型   0：无需展示；1：初始化；2：更新数据；9：错误信息
  showType: 0 | 1 | 2 | 9;
  // 是否允许聊天框输入
  chatEnable: boolean;
  // 错误信息
  errorMessage?: string;
  // 消息集合 
  msglist: Array<{
    [key: string]: any
    data?: any; // 消息内容
    cardFileUrl?: string
    cardId?: string
  }>;
  source?: TSource;
  // 快捷回复内容列表
  quickReplies?: TQuick;
  // 快捷回复名称
  // 一直显示快捷回复内容列表的内容
  alwaysShowQuickReplies?: boolean
}

// 流式接收对象 ×
export interface FetchMsgObject {
  [key: string]: any
  id?: string
  message_id: string
  task_id: string
  created_at: string
  // 事件名称
  event: string
  // 状态码
  status: number
  // 错误信息
  message: string
  // 正确回答
  answer: string
  // 进度信息
  data?: {
    id: string  // 单条进度id
    status: 'started' | 'failed' | 'succeeded' | 'waiting'
    title: string  // 具体内容
  }
}

export interface TBreakQA_Option extends CustomOption {
  data: {
    taskid?: string // 系统默认数据结构的taskid
    controller?: any  // 当前fetch的controller
  }
}

export interface TBeforeOpenChat_Option extends CustomOption {
  data: {
    currentId?: string  // 当前选中的会话id
    afterId: string     // 即将切换的会话id
  }
}

export type TFileChangeEvent = 'success' | 'error' | 'delete' | 'change'

export type TDirection = 'up' | 'down'

export type selectionchangeProps = {
  value: string;
  start: number;
  end: number;
}

export interface HANDLERS {
  /** renderMessageContent 自定义消息渲染
   * @param msg 
   * @param ctx 
   * @returns ReactNode
   */
  renderMessageContent?: (msg: MessageProps, ctx: CTX) => ReactNode

  /** onScroll 聊天区域滚动事件触发
   * @param ev 
   * @param ctx 
   * @returns success=true时content值将作为loading的内容加载
   */
  onScrollTo?: (ev: any, ctx: CTX, direction: TDirection) => Promise<{ success: boolean, content?: any }>

  /** onQuickReplyClick 快捷短语点击时、渲染到输入框前触发
   * @param item 
   * @param ctx 
   * @returns string=渲染到输入框的文字&同意系统继续行为
   *          false=否定系统继续行为
   */
  onQuickReplyClick?: (item: any, ctx: CTX) => string | false

  /** beforeSendMessage 点击发送按钮时、渲染右侧问题前触发
  * @param msg 
  * @param ctx 
  * @returns MsgProps=修改后的消息数据&同意系统继续行为
  *          false=否定系统继续行为
  */
  beforeSendMessage?: (msg: MsgProps, ctx: CTX) => MsgProps | false

  /** sendMessage 渲染右侧问题后、发送问答交易前触发
   * @param inVal 输入框的文字
   * @param ctx 
   * @returns string=修改后的文字&同意系统继续行为
   *          false=否定系统继续行为
   */
  sendMessage?: (inVal: string, ctx: CTX) => string | false

  /** breakQA 发送问答之后、点击中断发送时、内部controller.abort()之前触发
   * @param opt 
   * @returns next=同意系统继续行为
   *          isAbort=否定系统继续行为时，需告知系统是否已中断请求，只做dom更新
   */
  onBreakQA?: (opt: TBreakQA_Option) => { next: boolean, isAbort: boolean }

  /** beforeAppendMessage 生成任意消息时、追加到消息列表前触发
   * @param msg 
   * @param ctx 
   * @returns MsgProps=修改后的消息数据&同意系统继续行为
   *          false=否定系统继续行为
   */
  beforeAppendMessage?: (msg: MsgProps, ctx: CTX) => MsgProps | false

  /** onFeedback 消息反馈点击按钮时、动态效果和发送交易前触发
   * @param options msg、 likes、 dislikes
   * @returns next=同意系统继续行为
   *          succeed=否定系统继续行为next=false时，读取消息反馈是否成功，只做动态效果
   */
  onFeedback?: (options: PreFeedBack) => { next: boolean, succeed: boolean }

  /** onBroad 语音播报点击按钮时、发送交易前触发
   * @param options text 需要播报的文字
   * @returns 
   */
  onBroad?: (options: PreVoice) => Promise<{ next: boolean, succeed: boolean, data: Blob }>

  /** getMsgActionOptions 根据参数获取当前消息的反馈数据
   * @param options msg、 key、 ctx
   * @returns className?
   */
  getMsgActionOptions?: (options: { msg: MsgProps, key: string, ctx: CTX }) => { [key: string]: any }

  /** onselectionchange 输入框文字选中状态变化后触发
   * @param options value、start、end
   * @param ctx 
   * @returns 
   * */
  onselectionchange?: (options: selectionchangeProps, ctx: CTX) => void;

  /** onFileChange 选择文件后、文件列表中文件信息变化后触发
   * @param ev 
   * @param fileList 
   * @param ctx 
   * @returns 
   */
  onFileChange?: (ev: TFileChangeEvent, fileList: Array<FileItem>, ctx: CTX) => void;

  /** beforeSpeechToText 语音输入完成之后、动态效果(语音转文字处理中...)和发送语音转文字交易之前触发
   * @param options voice:Blob[]记录的录音数据
   * @returns next=同意系统继续行为
   *          succeed=否定系统继续行为next=false时，语音转文字是否成功，只做动态效果
   *                  (成功则清空输入框文字、显示发送按钮，注意如果自定义设置setText请延时；失败则显示重试和取消按钮)
   */
  beforeSpeechToText?: (options: PreSpeechToText) => { next: boolean, succeed?: boolean }

  /** onBeforeOpenChat 会话列表中点击某个会话时、确定切换和resetList([])和历史消息交易前触发
   * @param options currentId 当前选中的会话id,可能无值
   *                afterId 即将切换的会话id
   * @returns true=同意系统继续行为
   */
  onBeforeOpenChat?: (options: TBeforeOpenChat_Option) => boolean
  /** onAfterOpenChat 系统完成切换(确定切换和resetList([])和历史消息交易)后触发
   * @param options openedId 当前打开的会话id
   * @returns 
   */
  onAfterOpenChat?: (options: { data: { openedId: string }, ctx: CTX }) => void

  /** onActionClick 消息工具栏图标点击时的事件触发
   * @param options.data.key 图标的key
   * @param options.data.msg 消息数据
   * @param options.ctx 
   * @returns 
   */
  onActionClick?: (options: { data: { key: ToolBarType, msg: MsgProps }, ctx: CTX }) => void

  /**
   * 当右侧附加内容关闭时的回调函数。
   * 
   * @param ctx - 回调函数的上下文对象。
   * @returns 无返回值。
   */
  onRightAdditionClose?: (ctx: CTX) => void

  /**
   * 指令 @ 的选中确认事件。
   *
   * @param cautionItem - 选中的对象。
   * @param ctx - 上下文对象。
   * @returns 无返回值，此函数执行某些副作用操作。
   */
  onConfirmAite?: (cautionItem: CautionItem, ctx: CTX) => void
}
