"use client"
import dynamic from 'next/dynamic';
import { useEffect, useRef, useState } from 'react';
import '@/deps/live2d.min.js'
import useVoice2Txt from "@/hooks/useVoice2txt";
import useTxt2Voice from '@/hooks/useTxt2Voice';
import axios from 'axios';
import * as PIXI from 'pixi.js';
import { Live2DModel } from 'pixi-live2d-display/cubism2';


//import "@/deps/live2dcubismcore.min.js"
export default function Home() {
    function draggable(model: any) {
        model.buttonMode = true;
        model.on("pointerdown", (e: any) => {
            model.dragging = true;
            model._pointerX = e.data.global.x - model.x;
            model._pointerY = e.data.global.y - model.y;
        });
        model.on("pointermove", (e: any) => {
            if (model.dragging) {
                model.position.x = e.data.global.x - model._pointerX;
                model.position.y = e.data.global.y - model._pointerY;
            }
        });
        model.on("pointerupoutside", () => (model.dragging = false));
        model.on("pointerup", () => (model.dragging = false));
    }

    function addFrame(model: any) {
        const foreground = PIXI.Sprite.from(PIXI.Texture.WHITE);
        foreground.width = model.internalModel.width;
        foreground.height = model.internalModel.height;
        foreground.alpha = 0.2;

        model.addChild(foreground);

        checkbox("Model Frames", (checked: any) => (foreground.visible = checked));
    }

    function addHitAreaFrames(model: any) {
        try {
            //@ts-ignore
            const hitAreaFrames = new PIXI.live2d.HitAreaFrames();

            model.addChild(hitAreaFrames);

            checkbox("Hit Area Frames", (checked: any) => (hitAreaFrames.visible = checked));
        } catch (err) {

        }

    }

    function checkbox(name: any, onChange: any) {
        const id = name.replace(/\W/g, "").toLowerCase();

        let checkbox = document.getElementById(id);

        if (!checkbox) {
            const p = document.createElement("p")!;
            p.innerHTML = `<input type="checkbox" id="${id}"> <label for="${id}">${name}</label>`;

            document!.getElementById("control")!.appendChild(p);
            checkbox = p.firstChild as HTMLElement;
        }

        checkbox.addEventListener("change", () => {
            //@ts-ignore
            onChange(checkbox.checked);
        });
        //@ts-ignore
        onChange(checkbox.checked);
    }
    const send = (inputText: string) => {
        setResponse(inputText)
        if (!inputText) return;
        console.log(inputText)
        let data = JSON.stringify({
            "messages": [
                {
                    "content": `回答用户的问题，尽可能简短。`,
                    "role": "system"
                },
                {
                    "content": inputText,
                    "role": "user"
                }
            ],
            "model": "deepseek-chat",
            "frequency_penalty": 0,
            "max_tokens": 2048,
            "presence_penalty": 0,
            "stop": null,
            "stream": false,
            "temperature": 1,
            "top_p": 1
        });

        let config = {
            method: 'post',
            maxBodyLength: Infinity,
            url: 'https://api.deepseek.com/chat/completions',
            headers: {
                'Content-Type': 'application/json',
                'Accept': 'application/json',
                'Authorization': 'Bearer sk-dd24ae704e8d4939aeed8f050d04d36b'
            },
            data: data
        };
        try {
            axios(config)
                .then((response) => {
                    console.log(`response`, response);
                    console.log(response.data);
                    typeof speak !== 'undefined' && speak(response.data.choices[0].message.content);
                    setResponse(response.data.choices[0].message.content);
                })
                .catch((error) => {
                    setResponse(error!.toString());
                    console.log(error);
                });
        } catch (error) {
            setResponse(error!.toString());
            console.log(error);
        }

    }

    const { start, end, text, isListening, error } = useVoice2Txt({
        lang: 'cmn-Hans-CN',
        continuous: false
    });

    const {
        isSpeaking,
        speak,
        stop
    } = useTxt2Voice();
    const [inputText, setInputText] = useState("");
    const isMouthOpen = useRef(false);
    const [response, setResponse] = useState("");
    useEffect(() => {
        console.log(text, error)
        if (!text) return;
        send(text);
        if (error) {
            setResponse(error);
            return;
        }
    }, [text, error]);
    const [model, setModel] = useState<Live2DModel>();
    useEffect(() => {
        if (!isSpeaking) {
            isMouthOpen.current = false;
        }
    }, [isSpeaking]);

    useEffect(() => {
        if (!isListening && !isSpeaking) { }
    }, [isListening]);

    useEffect(() => {
        // expose PIXI to window so that this plugin is able to
        // reference window.PIXI.Ticker to automatically update Live2D models
        //@ts-ignore
        typeof window !== 'undefined' && (window.PIXI = PIXI);
        (async function () {
            const app = new PIXI.Application({
                view: document.getElementById('canvas') as HTMLCanvasElement,
            });

            const model = await Live2DModel.from('https://cdn.jsdelivr.net/gh/guansss/pixi-live2d-display/test/assets/shizuku/shizuku.model.json');

            app.stage.addChild(model);
            const scaleX = (innerWidth * 0.4) / model.width;
            const scaleY = (innerHeight * 0.8) / model.height;

            // fit the window
            model.scale.set(0.3);

            model.y = innerHeight * 0.1;

            draggable(model);
            addFrame(model);
            addHitAreaFrames(model);
            setModel(model);
            model.on('hit', (hitAreas) => {
                if (hitAreas.includes('body')) {
                    model.motion('tap_body');
                    model.motion('speak')
                }
            });
        })();
    }, [])
    return (

        <main>
            {
                typeof window !== 'undefined'
                && typeof window.Live2D !== 'undefined'
                && (<div className='flex w-full flex-col h-full items-center justify-center relative'>
                    <canvas className='w-full h-[40%]' id="canvas"></canvas>
                    <div className='absolute right-[20vw] top-4 bg-white rounded w-[20vw] h-auto text-sm text-black'>{response ? response : "请输入文字和我聊天吧"}</div>
                    <div id="control"></div>
                    <button onClick={start}>语音输入</button>
                    <button onClick={end}>结束语音输入</button>
                    <input className='text-black' value={inputText} onChange={(e) => {
                        setInputText(e.target.value);
                        console.log(e.target.value)
                    }}></input>
                    <button onClick={() => {
                        send(inputText);
                        setInputText("");
                    }}>发送</button>
                </div>)
            }
        </main>
    );
}