
import consola from "consola";
import { watch, nextTick, onMounted, onUnmounted, ref } from 'vue'
import TRTC from "trtc-js-sdk";
import type { LocalStream, Client, RemoteStream } from "trtc-js-sdk";
import { useRtcStore } from "/@/store/modules/rtc";
import Dialog from '/@/components/basic/dialog'

let localClient: Client;
let localStream: LocalStream;
const invitedRemoteStreams = ref<RemoteStream[]>([]);
const muteAudioLeader = ref(false);
const muteVideoLeader = ref(false);


export const updateDevice = async () => {
    console.log("updateDevice");
    const rtcStore = useRtcStore()
    const microphoneItems = await TRTC.getMicrophones();
    microphoneItems.forEach((item) => {
        item['value'] = item.deviceId;
    });
    if (microphoneItems?.length) {
        rtcStore.setAudioDeviceId(microphoneItems[0].deviceId)
    } else {
        rtcStore.setAudioDeviceId('')
    }

}


const checkoutIsExistAudioInput = async () => {
    const result = await TRTC.checkSystemRequirements()
    console.log('result', result)
}

// interface UseRtcSdkType {
//     createRTCSocket: () => Promise<void>
// }

async function createLocalStream() {
    try {
        const rtcStore = useRtcStore()
        localStream = TRTC.createStream({
            userId: rtcStore.userId,
            audio: true,
            video: false,
            microphoneId: rtcStore.audioDeviceId,
        });

        await localStream.initialize();

        if (rtcStore.audioMuted) {
            localStream.muteAudio();
        }
    } catch (error) {
        console.log(error, "createStream");
    }
}

async function createRTCSocket(): Promise<void> {
    try {
        const rtcStore = useRtcStore()
        await checkoutIsExistAudioInput();

        await updateDevice()
        // const microphoneItems = await TRTC.getMicrophones();

        // if (microphoneItems?.length) {

        // }
        await handleJoin();

    } catch (error) {
        consola.error({
            tag: 'createRTCSocket',
            message: error
        })
    }
}
async function handleJoin() {
    try {
        // let res = await apis.getSign({ userId: store.getters["rtc/userId"] });
        const rtcStore = useRtcStore()
        localClient = TRTC.createClient({
            mode: "rtc",
            sdkAppId: parseInt(rtcStore.sdkAppId, 10),
            userId: rtcStore.userId,
            userSig: rtcStore.genUserSig,
            useStringRoomId: true,
            enableAutoPlayDialog: false,
        });
        installEventHandlers();

        await localClient.join({ roomId: rtcStore.roomId });
        // store.commit("rtc/setIsJoined", true);
        rtcStore.setIsJoined(true)
        // inviteLink.value = store.commit("rtc/createShareLink");
    } catch (error) {
        console.error(error, "error-----------");
    }

    await createLocalStream();
    await handlePublish();
    localStream
        .play("local")
        .then(() => {
            consola.info({
                message: "音采源",
                tag: 'rtc:audio'
            })
        })
        .catch((e) => {
            console.log(localStream);
        });

    localStream.on("error", (error) => {
        if (error.getCode() === 0x4043) {
            // 自动播放受限导致播放失败，此时引导用户点击页面。
            // 在点击事件的回调函数中，执行 stream.resume();
            Dialog.confirm({
                showCloseIcon: false,
                okText: "确定",
                content:
                    "<span style='font-size: 16px; line-height: 1.5;'>在用户与网页产生交互（例如点击、触摸页面等）之前，网页将被禁止播放带有声音的媒体。点击恢复播放<span/>",
                title: "隐私条款：",
                single: true,
                func: (state) => {
                    if (state == "ok") {
                        localStream.resume();
                    }
                },
            });
        }
    });
}

async function handlePublish() {
    const rtcStore = useRtcStore()

    if (!rtcStore.isJoined) {
        return;
    }
    if (rtcStore.isPublished) {
        return;
    }
    if (!rtcStore.isLeader) {
        return;
    }
    try {
        await localClient.publish(localStream);
        // store.commit("rtc/setIsPublished", true);
        rtcStore.setIsPublished(true)
    } catch (error) {
        console.error(error, "---------------handlePublish--------------------");
    }
}

// async function handleStartShare() {
//     shareClient = new ShareClient({
//         sdkAppId: parseInt(store.getters["rtc/sdkAppId"], 10),
//         userId: `share${store.getters["rtc/userId"]}`,
//         roomId: store.getters["rtc/roomId"],
//         secretKey: store.getters["rtc/secretKey"],
//         useStringRoomId: true,
//     });
//     try {
//         await shareClient.join();
//         await shareClient.publish();
//         console.log("Start share screen success");
//         store.isShared = true;
//     } catch (error) {
//         console.error(`Start share error: ${error.message_}`);
//     }
// }

async function handleUnpublish() {
    const rtcStore = useRtcStore()
    if (!rtcStore.isJoined) {
        return;
    }
    if (!rtcStore.isPublished) {
        return;
    }
    try {
        await localClient.unpublish(localStream);
        // store.commit("rtc/setIsPublished", false);
        rtcStore.setIsPublished(false)
    } catch (error) {
        console.error(error, "-----------handleUnpublish--------------");
    }
}

async function handleLeave() {
    const rtcStore = useRtcStore()
    if (rtcStore.isPublished) {
        await handleUnpublish();
    }
    try {
        uninstallEventHandlers();
        await localClient.leave();
        localClient.destroy();
        // localClient = null;
        invitedRemoteStreams.value.forEach((item) => {
            item.stop();
        });
        invitedRemoteStreams.value = [];
        rtcStore.setVideoDeviceId('')
        rtcStore.setAudioDeviceId('')
        // store.commit("rtc/setVideoDeviceId", "");
        // store.commit("rtc/setAudioDeviceId", "");

        if (localStream) {
            localStream.stop();
            localStream.close();
            // localStream = null;
            console.log("有执行到这里-------------");
        }
    } catch (error) {
        console.error(error, "-----------handleLeave--------------");
    }
}

function installEventHandlers() {
    if (!localClient) {
        return;
    }
    localClient.on("error", handleError);
    localClient.on("client-banned", handleBanned);
    localClient.on("peer-join", handlePeerJoin);
    localClient.on("peer-leave", handlePeerLeave);
    localClient.on("stream-added", handleStreamAdded);
    localClient.on("stream-subscribed", handleStreamSubscribed);
    localClient.on("stream-removed", handleStreamRemoved);
    localClient.on("stream-updated", handleStreamUpdated);
    localClient.on("mute-video", handleMuteVideo);
    localClient.on("mute-audio", handleMuteAudio);
    localClient.on("unmute-video", handleUnmuteVideo);
    localClient.on("unmute-audio", handleUnmuteAudio);
}

function uninstallEventHandlers() {
    if (!localClient) {
        return;
    }
    localClient.off("error", handleError);
    localClient.off("error", handleError);
    localClient.off("client-banned", handleBanned);
    localClient.off("peer-join", handlePeerJoin);
    localClient.off("peer-leave", handlePeerLeave);
    localClient.off("stream-added", handleStreamAdded);
    localClient.off("stream-subscribed", handleStreamSubscribed);
    localClient.off("stream-removed", handleStreamRemoved);
    localClient.off("stream-updated", handleStreamUpdated);
    localClient.off("mute-video", handleMuteVideo);
    localClient.off("mute-audio", handleMuteAudio);
    localClient.off("unmute-video", handleUnmuteVideo);
    localClient.off("unmute-audio", handleUnmuteAudio);
}

function handleMuteVideo(event) {
    console.log(`[${event.userId}] mute video`);
    if (event.userId.indexOf("leader") > -1) {
        muteVideoLeader.value = true;
    }
}

function handleMuteAudio(event) {
    if (event.userId.indexOf("leader") > -1) {
        muteAudioLeader.value = true;
    }
    console.log(event, `[] mute audio`);
}

function handleUnmuteVideo(event) {
    console.log(`[${event.userId}] unmute video`);
    if (event.userId.indexOf("leader") > -1) {
        muteVideoLeader.value = false;
    }
}

function handleUnmuteAudio(event) {
    console.log(`[${event.userId}] unmute audio`);
    if (event.userId.indexOf("leader") > -1) {
        muteAudioLeader.value = false;
    }
}

function handleError(error) {
    console.log(`LocalClient error: ${error.message_}`);
}

function handleBanned(error) {
    console.log(`Client has been banned for ${error.message_}`);
}

function handlePeerJoin(event) {
    const { userId } = event;
    if (userId !== "local-screen") {
        console.log(`Peer Client [${userId}] joined`);
    }
}

function handlePeerLeave(event) {
    const { userId } = event;
    if (userId !== "local-screen") {
        console.log(`[${userId}] leave`);
    }
}

function handleStreamAdded(event) {
    const remoteStream = event.stream;
    const id = remoteStream.getId();
    const userId = remoteStream.getUserId();
    const rtcStore = useRtcStore()

    console.log(remoteStream, "-------------remoteStream");

    if (remoteStream.getUserId() === rtcStore.userId) {
        // don't need to screen shared by us
        localClient.unsubscribe(remoteStream).catch((error) => {
            console.info(`unsubscribe failed: ${error.message_}`);
        });
    } else {
        console.log(
            `remote stream added: [${userId}] ID: ${id} type: ${remoteStream.getType()}`
        );
        localClient.subscribe(remoteStream).catch((error) => {
            console.info(`subscribe failed: ${error.message_}`);
        });
    }
}

async function handleStreamSubscribed(event) {
    const remoteStream = event.stream;
    const rtcStore = useRtcStore()
    const remoteUserId = remoteStream.getUserId()
    const remoteId = remoteStream.getId()
    if (remoteUserId == rtcStore.userId) {
        return;
    }

    if (!rtcStore.isUserInRemoteStream(remoteUserId)) {
        rtcStore.pushRemoteStreams(remoteStream)
        // debugger
    }
    await nextTick();
    setTimeout(async () => {
        try {
            await remoteStream
                .play(remoteId)
            consola.info({
                message: "客音源",
                tag: 'rtc:audio'
            })

        } catch (error) {
          
            Dialog.confirm({
                showCloseIcon: false,
                okText: "确定",
                content:
                    "<span style='font-size: 16px; line-height: 1.5;'>在用户与网页产生交互（例如点击、触摸页面等）之前，网页将被禁止播放带有声音的媒体。点击恢复播放<span/>",
                title: "隐私条款：",
                single: true,
                func: (state) => {
                    if (state == "ok") {
                        remoteStream.resume();
                    }
                },
            });
        }

    }, 200);
    // console.info(
    //     remoteStream.userId_,
    //     rtcStore,
    //     "handleStreamSubscribedhandleStreamSubscribed.value"
    // );

    // if (
    //     !invitedRemoteStreams.value.some(
    //         (item) => item.userId_ == remoteStream.userId_
    //     )
    // ) {
    //     debugger
    //     invitedRemoteStreams.value.push(remoteStream);
    // }

    // console.log(invitedRemoteStreams.value, "invitedRemoteStreams.value");

    // await nextTick();
    // setTimeout(() => {
    //     console.log(remoteStream.userId_, "remoteStream.getId()");
    //     remoteStream
    //         .play(remoteStream.userId_)
    //         .then(() => {
    //             console.log(`RemoteStream play success`, 88888888888888888888);
    //         })
    //         .catch((error) => {
    //             console.log(`RemoteStream play failed:  error: ${error.message_}`);
    //         });
    // }, 100);

    // const remoteStream = event.stream;
    // const userId = remoteStream.getUserId();
    // console.log(`RemoteStream subscribed: [${userId}]`);
}

function handleStreamRemoved(event) {
    const remoteStream = event.stream;
    const userId = remoteStream.getUserId();
    console.log(`RemoteStream removed: [${userId}]`);
}

function handleStreamUpdated(event) {
    const remoteStream = event.stream;
    const userId = remoteStream.getUserId();
    console.log(
        `RemoteStream updated: [${userId}] audio:${remoteStream.hasAudio()} video:${remoteStream.hasVideo()}`
    );
}

let switchDevice = async ({ videoId, audioId }) => {
    const rtcStore = useRtcStore()
    if (!rtcStore.isJoined) {
        return;
    }
    if (videoId) {
        try {
            await localStream.switchDevice("video", videoId);
        } catch (error) { }
    }
    if (audioId) {
        try {
            await localStream.switchDevice("audio", audioId);
        } catch (error) { }
    }
};



export function useRtcSdk() {
    return {
        createRTCSocket,
        handleJoin,
        handleLeave,
        localStream,
        client: localClient
    }
}


