import {useContext, useEffect, useRef, useState} from "react";
import {GlobalContext} from "../../context/GlobalContext.ts";
import {del, get, post, put, websocketUrl} from "../../util/AjaxUtils.ts";
import {Col, Divider, Row, Spin} from "antd";
import useMessage from "antd/es/message/useMessage";
import AiHelperText from "./text/AiHelperText.tsx";
import AiHelperMod from "./mod/AiHelperMod.tsx";
import {IProjMod} from "../../interfaces/proj/IProj.ts";
import {MAX_MOD_SIZE} from "../../route/proj/edit/ProjConfigModList.tsx";
import {useNavigate} from "react-router-dom";
import {uuid} from "../../util/CommonUtil.ts";

type PropsType = {
    projId: string;
    projIntroduction?: string;
    projDesc?: string;
    isFree: boolean;
}

type ProjModType = {
    id: string,
    name: string,
    desc: string
}

export default function AiHelper(props: PropsType) {
    const globalContext = useContext(GlobalContext);
    const pingTimeout = useRef(-1);
    const ws = useRef<WebSocket | null>(null);
    const [messageApi, messageApiHolder] = useMessage();
    const [projIntroduction, setProjIntroduction] = useState<string>(props.projIntroduction ? props.projIntroduction : '');
    const [newProjIntroduction, setNewProjIntroduction] = useState<string>('');
    const [isProjIntroductionLoading, setIsProjIntroductionLoading] = useState(false);

    const [projDesc, setProjDesc] = useState<string>(props.projDesc ? props.projDesc : '');
    const [newProjDesc, setNewProjDesc] = useState<string>('');
    const [isProjDescLoading, setIsProjDescLoading] = useState(false);

    const [projModArray, setProjModArray] = useState<IProjMod[]>([]);
    const [newProjModArray, setNewProjModArray] = useState<ProjModType[]>([]);
    const [isProjModArrayLoading, setIsProjModArrayLoading] = useState(false);
    const nav = useNavigate();


    const ping = () => {
        clearTimeout(pingTimeout.current);
        pingTimeout.current = setTimeout(() => {
            if (!ws.current) {
                return;
            }
            ws.current.send("PING");
            ping();
        }, 3000);
    }

    const websocket = () => {
        ws.current = new WebSocket(`${websocketUrl()}/ws/ai/${globalContext.user.userId}`);
        ws.current.onopen = (event) => {
            console.log('打开', event);
            ping();
        }
        ws.current.onmessage = (event) => {
            if (event.data == 'PONE') {
                return;
            }
            const data = JSON.parse(event.data);
            if (data.projId != props.projId) {
                return;
            }
            if (data.type == 'REFRESH_PROJ_INTRODUCTION') {
                setIsProjIntroductionLoading(false);
                setNewProjIntroduction(data.content);
            } else if (data.type == 'REFRESH_PROJ_DESC') {
                setIsProjDescLoading(false);
                setNewProjDesc(data.content);
            } else if (data.type == 'REFRESH_PROJ_MODS') {
                setIsProjModArrayLoading(false);
                const projMods = JSON.parse(data.content) as ProjModType[];
                projMods.forEach(projMod => projMod.id = uuid())
                setNewProjModArray(projMods);
            } else if (data.type == 'REFRESH_PROJ_MOD_FIELDS') {
                listMods();
            }
        }
        ws.current.onerror = (event) => {
            console.log('error', event);
        }
        ws.current.onclose = (event) => {
            console.log('close', event);
            websocket()
        }
    }

    const listMods = () => {
        get<IProjMod[]>({
            messageApi,
            url: `/api/proj-mod/list/proj-id/${props.projId}`,
            onBefore() {
                setIsProjModArrayLoading(true);
            },
            onSuccess({data}) {
                setProjModArray(data);
            },
            onFinally() {
                setIsProjModArrayLoading(false);
            }
        })
    }

    const generateProjIntroduction = () => {
        ws.current?.send(JSON.stringify({
            type: 'REFRESH_PROJ_INTRODUCTION',
            projId: props.projId
        }));
        ping();
        setIsProjIntroductionLoading(true);
    }

    const generateProjDesc = () => {
        ws.current?.send(JSON.stringify({
            type: 'REFRESH_PROJ_DESC',
            projId: props.projId
        }));
        ping();
        setIsProjDescLoading(true);
    }

    const generateProjModArray = () => {
        ws.current?.send(JSON.stringify({
            type: 'REFRESH_PROJ_MODS',
            projId: props.projId
        }));
        ping();
        setIsProjModArrayLoading(true);
    }

    /**
     * 保存简介
     */
    const updateProjIntroduction = (content: string) => {
        put<any>({
            messageApi,
            url: `/api/proj/update-introduction/${props.projId}`,
            body: {
                content: content
            },
            onBefore() {
                setIsProjIntroductionLoading(true);
            },
            onSuccess() {
                messageApi.success('保存成功');
                setProjIntroduction(content);
                setNewProjIntroduction('');
            },
            onFinally() {
                setIsProjIntroductionLoading(false)
            }
        })
    }

    /**
     * 保存详情
     */
    const updateProjDesc = (content: string) => {
        put<any>({
            messageApi,
            url: `/api/proj/update-desc/${props.projId}`,
            body: {
                content: content
            },
            onBefore() {
                setIsProjDescLoading(true);
            },
            onSuccess() {
                messageApi.success('保存成功').then();
                setProjDesc(content);
                setNewProjDesc('');
            },
            onFinally() {
                setIsProjDescLoading(false)
            }
        })
    }

    useEffect(() => {
        if (!props.projId) {
            return;
        }
        listMods();
        websocket();
    }, [globalContext.user.userId, props.projId]);

    return (
        <>
            {messageApiHolder}
            <Row>
                <Col span={24}>
                    <Spin tip="正在处理，请稍后..." size="small" spinning={isProjIntroductionLoading}>
                        <AiHelperText title="项目简介"
                                      text={projIntroduction}
                                      newText={newProjIntroduction}
                                      maxLength={1500}
                                      handleGenerate={() => {
                                          generateProjIntroduction();
                                      }}
                                      handleSave={(text) => {
                                          updateProjIntroduction(text);
                                      }}
                        />
                    </Spin>
                </Col>
                <Col span={24}>
                    <Divider dashed/>
                    <Spin tip="正在处理，请稍后..." size="small" spinning={isProjDescLoading}>
                        <AiHelperText title="项目详情"
                                      text={projDesc}
                                      newText={newProjDesc}
                                      maxLength={1500}
                                      handleGenerate={() => {
                                          generateProjDesc();
                                      }}
                                      handleSave={(text) => {
                                          updateProjDesc(text);
                                      }}
                        />
                    </Spin>
                </Col>
                <Col span={24}>
                    <Divider dashed/>
                    <Spin tip="正在处理，请稍后..." size="small" spinning={isProjModArrayLoading}>
                        <AiHelperMod mods={projModArray}
                                     newMods={newProjModArray}
                                     handleGenerate={() => {
                                         generateProjModArray();
                                     }}
                                     handleSave={(index, mod) => {
                                         if(projModArray.length > MAX_MOD_SIZE) {
                                            messageApi.error(`模块最大数量为${MAX_MOD_SIZE}`);
                                            return;
                                         }
                                         post<any>({
                                             messageApi,
                                             url: `/api/proj-mod/save-ai/${props.projId}`,
                                             body: {
                                                name: mod.name,
                                                desc: mod.desc,
                                             },
                                             onBefore() {
                                                 setIsProjModArrayLoading(true);
                                             },
                                             onSuccess() {
                                                messageApi.success('提交成功')
                                                listMods();
                                                newProjModArray.splice(index, 1);
                                                setNewProjModArray([
                                                    ...newProjModArray
                                                ]);
                                             },
                                             onFinally() {
                                                 setIsProjModArrayLoading(false);
                                             }
                                         })
                                     }}
                                     handleResaveField={(_index, projModId) => {
                                         post<any>({
                                             messageApi,
                                             url: `/api/proj-mod/resave-ai-field/${props.projId}/${projModId}`,
                                             onBefore() {
                                                 setIsProjModArrayLoading(true);
                                             },
                                             onSuccess() {
                                                 messageApi.success('提交成功')
                                                 listMods();
                                             },
                                             onFinally() {
                                                 setIsProjModArrayLoading(false);
                                             }
                                         })
                                     }}
                                     handleEdit={(_index, projModId, item) => {
                                         if(item.aiFieldStatus != 'SUCCESS') {
                                             messageApi.error('模块未处理完毕不能编辑');
                                             return;
                                         }
                                         if(props.isFree) {
                                             nav(`/proj-edit/config-mod-fedit/${props.projId}/${projModId}`)
                                         } else {
                                             nav(`/proj-edit/config-mod-edit/${props.projId}/${projModId}`)
                                         }
                                     }}
                                     handleRemove={(_index, projModId, item) => {
                                         if(item.aiFieldStatus != 'SUCCESS') {
                                            messageApi.error('模块未处理完毕不能删除');
                                            return;
                                         }
                                         del<any>({
                                             messageApi,
                                             url: `/api/proj-mod/remove/proj-id/${props.projId}/${projModId}`,
                                             onBefore() {
                                                 setIsProjModArrayLoading(true);
                                             },
                                             onSuccess() {
                                                 messageApi.success('删除成功');
                                                 listMods();
                                             },
                                             onFinally() {
                                                 setIsProjModArrayLoading(false);
                                             }
                                         })
                                     }}
                        />
                    </Spin>
                </Col>

            </Row>
        </>
    )
}