"use client";

import { LightButton } from "@/components/ui/buttons";
import { IconClick } from "@/components/ui/buttons";
import IMAGES from "@/config/images";
import { useAudioPlayer } from "@/hooks/useAudioPlayer";
import {
  TextSpeakerArraySchema,
  TextSpeakerItemSchema,
} from "@/lib/interfaces";
import { ChangeEvent, useEffect, useRef, useState } from "react";
import z from "zod";
import SaveList from "./SaveList";

import { useTranslations } from "next-intl";
import { getLocalStorageOperator } from "@/lib/browser/localStorageOperators";
import { genIPA, genLanguage } from "@/modules/translator/translator-action";
import { logger } from "@/lib/logger";
import PageLayout from "@/components/ui/PageLayout";
import { getTTSUrl, TTS_SUPPORTED_LANGUAGES } from "@/lib/bigmodel/tts";

export default function TextSpeakerPage() {
  const t = useTranslations("text_speaker");
  const textareaRef = useRef<HTMLTextAreaElement>(null);
  const [showSpeedAdjust, setShowSpeedAdjust] = useState(false);
  const [showSaveList, setShowSaveList] = useState(false);
  const [saving, setSaving] = useState(false);
  const [ipaEnabled, setIPAEnabled] = useState(false);
  const [speed, setSpeed] = useState(1);
  const [pause, setPause] = useState(true);
  const [autopause, setAutopause] = useState(true);
  const textRef = useRef("");
  const [language, setLanguage] = useState<string | null>(null);
  const [ipa, setIPA] = useState<string>("");
  const objurlRef = useRef<string | null>(null);
  const [processing, setProcessing] = useState(false);
  const { play, stop, load, audioRef } = useAudioPlayer();

  const { get: getFromLocalStorage, set: setIntoLocalStorage } =
    getLocalStorageOperator<typeof TextSpeakerArraySchema>(
      "text-speaker",
      TextSpeakerArraySchema,
    );

  useEffect(() => {
    const audio = audioRef.current;
    if (!audio) return;

    const handleEnded = () => {
      if (autopause) {
        setPause(true);
      } else {
        load(objurlRef.current!);
        play();
      }
    };
    audio.addEventListener("ended", handleEnded);
    return () => {
      audio.removeEventListener("ended", handleEnded);
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [audioRef, autopause]);

  const speak = async () => {
    if (processing) return;
    setProcessing(true);

    if (ipa.length === 0 && ipaEnabled && textRef.current.length !== 0) {
      const params = new URLSearchParams({
        text: textRef.current,
      });
      fetch(`/api/ipa?${params}`)
        .then((res) => res.json())
        .then((data) => {
          setIPA(data.ipa);
        })
        .catch((e) => {
          logger.error("生成 IPA 失败", e);
          setIPA("");
        });
    }

    if (pause) {
      // 如果没在读
      if (textRef.current.length === 0) {
        // 没文本咋读
      } else {
        setPause(false);

        if (objurlRef.current) {
          // 之前有播放
          load(objurlRef.current);
          play();
        } else {
          // 第一次播放
          try {
            let theLanguage = language;
            if (!theLanguage) {
              const tmp_language = await genLanguage(textRef.current.slice(0, 30));
              setLanguage(tmp_language);
              theLanguage = tmp_language;
            }

            theLanguage = theLanguage.toLowerCase().replace(/[^a-z]/g, '').replace(/^./, match => match.toUpperCase());

            // 检查语言是否在 TTS 支持列表中
            const supportedLanguages: TTS_SUPPORTED_LANGUAGES[] = [
              "Auto", "Chinese", "English", "German", "Italian", "Portuguese",
              "Spanish", "Japanese", "Korean", "French", "Russian"
            ];

            if (!supportedLanguages.includes(theLanguage as TTS_SUPPORTED_LANGUAGES)) {
              theLanguage = "Auto";
            }

            objurlRef.current = await getTTSUrl(
              textRef.current,
              theLanguage as TTS_SUPPORTED_LANGUAGES
            );
            load(objurlRef.current);
            play();
          } catch (e) {
            logger.error("播放音频失败", e);
            setPause(true);
            setLanguage(null);
            setProcessing(false);
          }
        }
      }
    } else {
      // 如果在读就暂停
      setPause(true);
      stop();
    }

    setProcessing(false);
  };

  const handleInputChange = (e: ChangeEvent<HTMLTextAreaElement>) => {
    textRef.current = e.target.value.trim();
    setLanguage(null);
    setIPA("");
    if (objurlRef.current) URL.revokeObjectURL(objurlRef.current);
    objurlRef.current = null;
    stop();
    setPause(true);
  };

  const letMeSetSpeed = (new_speed: number) => {
    return () => {
      setSpeed(new_speed);
      if (objurlRef.current) URL.revokeObjectURL(objurlRef.current);
      objurlRef.current = null;
      stop();
      setPause(true);
    };
  };

  const handleUseItem = (item: z.infer<typeof TextSpeakerItemSchema>) => {
    if (textareaRef.current) textareaRef.current.value = item.text;
    textRef.current = item.text;
    setLanguage(item.language);
    setIPA(item.ipa || "");
    if (objurlRef.current) URL.revokeObjectURL(objurlRef.current);
    objurlRef.current = null;
    stop();
    setPause(true);
  };

  const save = async () => {
    if (saving) return;
    if (textRef.current.length === 0) return;

    setSaving(true);

    try {
      let theLanguage = language;
      if (!theLanguage) {
        const tmp_language = await genLanguage(textRef.current.slice(0, 30));
        setLanguage(tmp_language);
        theLanguage = tmp_language;
      }

      let theIPA = ipa;
      if (ipa.length === 0 && ipaEnabled) {
        const tmp_ipa = await genIPA(textRef.current);
        setIPA(tmp_ipa);
        theIPA = tmp_ipa;
      }

      const save = getFromLocalStorage();
      const oldIndex = save.findIndex((v) => v.text === textRef.current);
      if (oldIndex !== -1) {
        const oldItem = save[oldIndex];
        if (theIPA) {
          if (!oldItem.ipa || oldItem.ipa !== theIPA) {
            oldItem.ipa = theIPA;
            setIntoLocalStorage(save);
          }
        }
      } else if (theIPA.length === 0) {
        save.push({
          text: textRef.current,
          language: theLanguage as string,
        });
      } else {
        save.push({
          text: textRef.current,
          language: theLanguage as string,
          ipa: theIPA,
        });
      }
      setIntoLocalStorage(save);
    } catch (e) {
      logger.error("保存到本地存储失败", e);
      setLanguage(null);
    } finally {
      setSaving(false);
    }
  };

  return (
    <PageLayout className="items-start py-4">
      {/* 文本输入区域 */}
      <div
        className="border border-gray-200 rounded-2xl"
        style={{ fontFamily: "Times New Roman, serif" }}
      >
        {/* 文本输入框 */}
        <textarea
          className="text-2xl resize-none focus:outline-0 min-h-64 w-full border-gray-200 border-b p-4"
          onChange={handleInputChange}
          ref={textareaRef}
        ></textarea>
        {/* IPA 显示区域 */}
        {(ipa.length !== 0 && (
          <div className="overflow-auto text-gray-600 h-18 border-gray-200 border-b px-4">
            {ipa}
          </div>
        )) || <div className="h-18"></div>}

        {/* 控制按钮区域 */}
        <div className="p-4 relative w-full flex flex-row flex-wrap gap-2 justify-center items-center">
          {/* 速度调节面板 */}
          {showSpeedAdjust && (
            <div className="bg-white p-6 rounded-2xl border-gray-200 border-2 shadow-2xl absolute left-1/2 -translate-x-1/2 -translate-y-full -top-4 flex flex-row flex-wrap gap-2 justify-center items-center z-10">
              <IconClick
                size={45}
                onClick={letMeSetSpeed(0.5)}
                src={IMAGES.speed_0_5x}
                alt="0.5x"
                className={speed === 0.5 ? "bg-gray-200" : ""}
              ></IconClick>
              <IconClick
                size={45}
                onClick={letMeSetSpeed(0.7)}
                src={IMAGES.speed_0_7x}
                alt="0.7x"
                className={speed === 0.7 ? "bg-gray-200" : ""}
              ></IconClick>
              <IconClick
                size={45}
                onClick={letMeSetSpeed(1)}
                src={IMAGES.speed_1x}
                alt="1x"
                className={speed === 1 ? "bg-gray-200" : ""}
              ></IconClick>
              <IconClick
                size={45}
                onClick={letMeSetSpeed(1.2)}
                src={IMAGES.speed_1_2_x}
                alt="1.2x"
                className={speed === 1.2 ? "bg-gray-200" : ""}
              ></IconClick>
              <IconClick
                size={45}
                onClick={letMeSetSpeed(1.5)}
                src={IMAGES.speed_1_5x}
                alt="1.5x"
                className={speed === 1.5 ? "bg-gray-200" : ""}
              ></IconClick>
            </div>
          )}
          {/* 播放/暂停按钮 */}
          <IconClick
            size={45}
            onClick={speak}
            src={pause ? IMAGES.play_arrow : IMAGES.pause}
            alt="playorpause"
            className={`${processing ? "bg-gray-200" : ""}`}
          ></IconClick>
          {/* 自动暂停按钮 */}
          <IconClick
            size={45}
            onClick={() => {
              setAutopause(!autopause);
              if (objurlRef) {
                stop();
              }
              setPause(true);
            }}
            src={autopause ? IMAGES.autoplay : IMAGES.autopause}
            alt="autoplayorpause"
          ></IconClick>
          {/* 速度调节按钮 */}
          <IconClick
            size={45}
            onClick={() => setShowSpeedAdjust(!showSpeedAdjust)}
            src={IMAGES.speed}
            alt="speed"
            className={`${showSpeedAdjust ? "bg-gray-200" : ""}`}
          ></IconClick>
          {/* 保存按钮 */}
          <IconClick
            size={45}
            onClick={save}
            src={IMAGES.save}
            alt="save"
            className={`${saving ? "bg-gray-200" : ""}`}
          ></IconClick>
          {/* 功能开关按钮 */}
          <div className="w-full flex flex-row flex-wrap gap-2 justify-center items-center">
            <LightButton
              selected={ipaEnabled}
              onClick={() => setIPAEnabled(!ipaEnabled)}
            >
              {t("generateIPA")}
            </LightButton>
            <LightButton
              onClick={() => {
                setShowSaveList(!showSaveList);
              }}
              selected={showSaveList}
            >
              {t("viewSavedItems")}
            </LightButton>
          </div>
        </div>
      </div>
      {/* 保存列表 */}
      {showSaveList && (
        <div className="mt-4 border border-gray-200 rounded-2xl overflow-hidden">
          <SaveList show={showSaveList} handleUse={handleUseItem}></SaveList>
        </div>
      )}
    </PageLayout>
  );
}
