const { FileOperationMachine } = require("../../connect/file");
const { ASR, ShortVoiceASR, TaskASR } = require("../../service/ASR");
const EventEmitter = require("events");
const { TTS, TaskTTS } = require("../../service/TTS");
const { HttpChunkMachine } = require("../../connect/restChuck");
const { HttpMachine } = require("../../connect/rest");
const { DHResource } = require("../../service/DH");
const { getDmOptions } = require("../../service/DM/DMUtils");
const { getTranslateOptions } = require("../../service/Translate");
const { getNowTime } = require("../../../utils/timeUtil");

class OSink {
  constructor(iSource,context) {
    Object.assign(this, iSource,context);
    this.connectStateMachine;
    this.eventEmitter = new EventEmitter();
    this.state = "init";
    this.runtimeStorage = {};
  }
  update(oSink) {
    Object.assign(this, oSink);
  }

  mutationUpdate(oSink) {
    this.close();
    Object.assign(this, oSink);
    this.open();
  }
  async open() {
    if (this.serviceType === "ASR") {
      if (this.config.integrateType === "sdk") {
        if (this.config.endpoint.mode === "realtime") {
          this.serviceInstance = new ASR(this);
          this.serviceInstance.eventEmitter.on("OnSentenceEnd", (res) => {
            console.log("【ASR】时间：%s 一句话识别结果：",getNowTime(), res);
            this.eventEmitter.emit("start", res);
          });
          await this.serviceInstance.init();
          await this.serviceInstance.start();
        } else if (this.config.endpoint.mode === "shortVoice") {
          this.serviceInstance = new ShortVoiceASR(this);
        } else if (this.config.endpoint.mode === "task") {
          this.serviceInstance = new TaskASR(this);
        }
      }
    } else if (this.serviceType === "TTS") {
      if (this.config.integrateType === "sdk") {
        if (this.config.endpoint.mode === "shortText") {
          this.serviceInstance = new TTS(this);
        } else if (this.config.endpoint.mode === "task") {
          this.serviceInstance = new TaskTTS(this);
        }
      }
    } else if (this.serviceType === "CHAT") {
      if (this.config.integrateType === "chunk") {
        this.serviceInstance = new HttpChunkMachine(this);
        this.serviceInstance.eventEmitter.on("start", (res) => {
          this.eventEmitter.emit("start", res);
        });
      } else if (this.config.integrateType === "rest") {
        this.serviceInstance = new HttpMachine(this);
        this.serviceInstance.eventEmitter.on("start", (res) => {
          this.eventEmitter.emit("start", res);
        });
      }
    } else if (this.serviceType === "DH") {
      if (this.config.integrateType === "sdk") {
        if (this.config.endpoint.mode === "cmd") {
          this.serviceInstance = new DHResource(this);
        }
      }
    } else if (this.serviceType === "DM") {
      if (this.config.integrateType === "rest") {
        this.serviceInstance = new HttpMachine(this);
        this.serviceInstance.eventEmitter.on("start", (res) => {
          this.eventEmitter.emit("start", res);
        });
      }
    }else if (this.serviceType === "Translate") {
      if (this.config.integrateType === "rest") {
        this.serviceInstance = new HttpMachine(this);
        this.serviceInstance.eventEmitter.on("start", (res) => {
          this.eventEmitter.emit("start", res);
        });
        this.serviceInstance.eventEmitter.on("query", (res) => {
          this.eventEmitter.emit("query", res);
        });
      }
    }
    this.state = "ready";
  }
  close() {
    this.state = "cancelled";
    if (this.serviceType === "ASR") {
      if (this.config.integrateType === "sdk") {
        if (this.config.endpoint.mode === "realtime") {
          this.serviceInstance?.stop();
        }
      }
    }
  }

  async start(params, data) {
    if(data==="success"){
      this.eventEmitter.emit("start", data);
      return;
    }
    if (this.serviceType === "ASR") {
      if (this.config.integrateType === "sdk") {
        if (this.config.endpoint.mode === "realtime") {
          this.serviceInstance.write(data);
        } else if (this.config.endpoint.mode === "shortVoice") {
          let result = await this.serviceInstance.speechRecognition(data.audio);
          this.eventEmitter.emit("start", result);
        } else if (this.config.endpoint.mode === "task") {
          let result = await this.serviceInstance.createRecTask(data.url);
          this.eventEmitter.emit("start", result);
        }
      }
    } else if (this.serviceType === "CHAT") {
      if (this.config.endpoint.sp === "openAI") {
        if (this.config.endpoint.mode === "text") {
          if (data.type === "prompt") {
            let options = this.getChatOpenAITextOptions(data.data.data.prompt);
            console.log("【CHAT】请求参数：", options);
            this.serviceInstance.send({ type: "START", params: options, cmd: "start", });
          }
        }
        if (this.config.endpoint.mode === "image") {
          if (data.type === "prompt") {
            let options = this.getChatOpenAIImageOptions(data.data.data);
            console.log("【CHAT】请求参数：", options);
            this.serviceInstance.send({ type: "START", params: options, cmd: "start", });
          }
        }
      }
    } else if (this.serviceType === "DH") {
      if (this.config.integrateType === "sdk") {
        if (this.config.endpoint.mode === "cmd") {
          let result = await this.serviceInstance.init();
          console.log("【DH】初始化结果：", result);
          this.runtimeStorage.topic = result.Payload.SessionId;
          this.eventEmitter.emit("start", result);
        }
      }
    } else if (this.serviceType === "DM") {
      if (this.config.integrateType === "rest") {
        console.log("【DM】事件：", data);
        //构造请求 options
        var options = await getDmOptions(data, this);
        console.log("【DM】请求参数：", options);
        //发送请求
        this.serviceInstance.send({ type: "START", params: options, cmd: "start", });
      }
    }
    this.state = "running";
  }

  stop() {
    this.state = "stopped";
    if (this.serviceType === "ASR") {
      if (this.config.integrateType === "sdk") {
        if (this.config.endpoint.mode === "realtime") {
          this.serviceInstance.stop();
        }
      }
    }
  }

  pause() {
    this.state = "paused";
    if (this.serviceType === "ASR") {
      if (this.config.integrateType === "sdk") {
        if (this.config.endpoint.mode === "realtime") {
          this.serviceInstance.stop();
        }
      }
    }
  }

  resume() {
    this.state = "running";
    if (this.serviceType === "ASR") {
      if (this.config.integrateType === "sdk") {
        if (this.config.endpoint.mode === "realtime") {
          this.serviceInstance.start();
        }
      }
    }
  }

  async query(params, data) {
    if (this.serviceType === "ASR") {
      if (this.config.integrateType === "sdk") {
        if (this.config.endpoint.mode === "shortVoice") {
          let result = await this.serviceInstance.speechRecognition(data.audio);
          this.eventEmitter.emit("query", result);
        } else if (this.config.endpoint.mode === "task") {
          let result = await this.serviceInstance.createRecTask(data.url);
          result.target = data.url;
          this.eventEmitter.emit("query", result);
        }
      }
    } else if (this.serviceType === "TTS") {
      if (this.config.integrateType === "sdk") {
        if (this.config.endpoint.mode === "shortText") {
          console.log("【TTS】发起时间：%s ",getNowTime());
          let result = await this.serviceInstance.textToVoice(data.text);
          this.eventEmitter.emit("query", result);
        } else if (this.config.endpoint.mode === "task") {
          let result = await this.serviceInstance.createTtsTask(data.text);
          result.target = data.text;
          this.eventEmitter.emit("query", result);
        }
      }
    } else if (this.serviceType === "DH") {
      if (this.config.integrateType === "sdk") {
        if (this.config.endpoint.mode === "cmd") {
          let result = await this.serviceInstance.command({
            topic: this.runtimeStorage.topic,
            text: data.text,
          });
          this.eventEmitter.emit("query", result);
        }
      }
    }else if (this.serviceType === "Translate") {
      if (this.config.integrateType === "rest") {
        //构造请求 options
        var options = await getTranslateOptions(data, this);
        console.log("【Translate】发起请求时间：%s ", getNowTime());
        //发送请求
        this.serviceInstance.send({ type: "START", params: options, cmd: "query", });
      }
    }
    this.state = "running";
  }

  async getTaskStatus(params, data) {
    if (this.serviceType === "ASR") {
      if (this.config.integrateType === "sdk") {
        if (this.config.endpoint.mode === "task") {
          let result = await this.serviceInstance.describeTaskStatus( data.taskId  );
          this.eventEmitter.emit("getTaskStatus", result);
        }
      }
    } else if (this.serviceType === "TTS") {
      if (this.config.integrateType === "sdk") {
        if (this.config.endpoint.mode === "task") {
          console.log("getTaskStatus+++++++++++++++++", data);
          let result = await this.serviceInstance.describeTtsTaskStatus( data.taskId);
          this.eventEmitter.emit("getTaskStatus", result);
        }
      }
    }
    this.state = "running";
  }

  getChatOpenAITextOptions(data) {
    let options = {
      method: "POST",
      url: this.config.endpoint.url,
      headers: this.config.headers,
      data: {
        prompt: data,
        ...this.config.params,
      },
    };
    return options;
  }
  getChatOpenAIImageOptions(data) {
    delete data.timestamp;
    let options = {
      method: "POST",
      url: this.config.endpoint.url,
      headers: this.config.headers,
      data: {
        ...data,
      },
    };
    return options;
  }
}

module.exports.OSink = OSink;
