import {
  getSentenseByWords,
  getTextContentBySentence,
  generateTempTranslateWords,
  Sentence,
} from "../sentense";
import { Word } from "@tingwu/core";

describe("sentense utilities", () => {
  describe("getSentenseByWords", () => {
    it("should return empty array for empty input", () => {
      expect(getSentenseByWords([])).toEqual([]);
    });

    it("should group words by sentenceId into sentences", () => {
      const words: Word[] = [
        {
          wid: "w1",
          sentenceId: "s1",
          beginTime: 0,
          endTime: 100,
          text: "Hello",
          tag: "",
        },
        {
          wid: "w2",
          sentenceId: "s1",
          beginTime: 100,
          endTime: 200,
          text: " World",
          tag: "",
        },
        {
          wid: "w3",
          sentenceId: "s2",
          beginTime: 200,
          endTime: 300,
          text: "Test",
          tag: "",
        },
      ];

      const result = getSentenseByWords(words);

      expect(result).toHaveLength(2);
      expect(result[0]).toEqual({
        sid: "s1",
        words: [words[0], words[1]],
      });
      expect(result[1]).toEqual({
        sid: "s2",
        words: [words[2]],
      });
    });

    it("should handle words with same sentenceId", () => {
      const words: Word[] = [
        {
          wid: "w1",
          sentenceId: "s1",
          beginTime: 0,
          endTime: 100,
          text: "First",
          tag: "",
        },
        {
          wid: "w2",
          sentenceId: "s1",
          beginTime: 100,
          endTime: 200,
          text: " Second",
          tag: "",
        },
        {
          wid: "w3",
          sentenceId: "s1",
          beginTime: 200,
          endTime: 300,
          text: " Third",
          tag: "",
        },
      ];

      const result = getSentenseByWords(words);

      expect(result).toHaveLength(1);
      expect(result[0].sid).toBe("s1");
      expect(result[0].words).toHaveLength(3);
      expect(result[0].words).toEqual(words);
    });

    it("should handle words with different sentenceIds", () => {
      const words: Word[] = [
        {
          wid: "w1",
          sentenceId: "s1",
          beginTime: 0,
          endTime: 100,
          text: "Sentence",
          tag: "",
        },
        {
          wid: "w2",
          sentenceId: "s2",
          beginTime: 100,
          endTime: 200,
          text: "One",
          tag: "",
        },
        {
          wid: "w3",
          sentenceId: "s3",
          beginTime: 200,
          endTime: 300,
          text: "Two",
          tag: "",
        },
      ];

      const result = getSentenseByWords(words);

      expect(result).toHaveLength(3);
      expect(result[0].sid).toBe("s1");
      expect(result[0].words).toHaveLength(1);
      expect(result[1].sid).toBe("s2");
      expect(result[1].words).toHaveLength(1);
      expect(result[2].sid).toBe("s3");
      expect(result[2].words).toHaveLength(1);
    });

    it("should handle single word", () => {
      const words: Word[] = [
        {
          wid: "w1",
          sentenceId: "s1",
          beginTime: 0,
          endTime: 100,
          text: "Single",
          tag: "",
        },
      ];

      const result = getSentenseByWords(words);

      expect(result).toHaveLength(1);
      expect(result[0]).toEqual({
        sid: "s1",
        words: [words[0]],
      });
    });
  });

  describe("getTextContentBySentence", () => {
    it("should concatenate all word texts in a sentence", () => {
      const sentence: Sentence = {
        sid: "s1",
        words: [
          {
            wid: "w1",
            sentenceId: "s1",
            beginTime: 0,
            endTime: 100,
            text: "Hello",
            tag: "",
          },
          {
            wid: "w2",
            sentenceId: "s1",
            beginTime: 100,
            endTime: 200,
            text: " World",
            tag: "",
          },
          {
            wid: "w3",
            sentenceId: "s1",
            beginTime: 200,
            endTime: 300,
            text: "!",
            tag: "",
          },
        ],
      };

      const result = getTextContentBySentence(sentence);
      expect(result).toBe("Hello World!");
    });

    it("should return empty string for sentence with no words", () => {
      const sentence: Sentence = {
        sid: "s1",
        words: [],
      };

      const result = getTextContentBySentence(sentence);
      expect(result).toBe("");
    });

    it("should handle single word sentence", () => {
      const sentence: Sentence = {
        sid: "s1",
        words: [
          {
            wid: "w1",
            sentenceId: "s1",
            beginTime: 0,
            endTime: 100,
            text: "Test",
            tag: "",
          },
        ],
      };

      const result = getTextContentBySentence(sentence);
      expect(result).toBe("Test");
    });
  });

  describe("generateTempTranslateWords", () => {
    it("should generate translate words from sentences", () => {
      const sentences: Sentence[] = [
        {
          sid: "s1",
          words: [
            {
              wid: "w1",
              sentenceId: "s1",
              beginTime: 0,
              endTime: 100,
              text: "Hello",
              tag: "",
            },
          ],
        },
        {
          sid: "s2",
          words: [
            {
              wid: "w2",
              sentenceId: "s2",
              beginTime: 100,
              endTime: 200,
              text: "World",
              tag: "",
            },
          ],
        },
      ];

      const getTranslate = (sentence: Sentence) => {
        if (sentence.sid === "s1") return "你好";
        return "世界";
      };

      const result = generateTempTranslateWords(sentences, getTranslate);

      expect(result).toHaveLength(2);
      expect(result[0]).toMatchObject({
        wid: "translate-1",
        sentenceId: "s1",
        text: "你好",
        beginTime: 0,
        endTime: 0,
        tag: "",
      });
      expect(result[1]).toMatchObject({
        wid: "translate-2",
        sentenceId: "s2",
        text: "世界",
        beginTime: 0,
        endTime: 0,
        tag: "",
      });
    });

    it("should generate unique IDs for each translate word", () => {
      const sentences: Sentence[] = [
        { sid: "s1", words: [] },
        { sid: "s2", words: [] },
        { sid: "s3", words: [] },
      ];

      const getTranslate = () => "translation";

      const result = generateTempTranslateWords(sentences, getTranslate);

      expect(result).toHaveLength(3);
      expect(result[0].wid).toBe("translate-1");
      expect(result[1].wid).toBe("translate-2");
      expect(result[2].wid).toBe("translate-3");
    });

    it("should handle empty sentences array", () => {
      const sentences: Sentence[] = [];
      const getTranslate = () => "translation";

      const result = generateTempTranslateWords(sentences, getTranslate);

      expect(result).toEqual([]);
    });
  });
});
