import { defineStore } from 'pinia';
import { computed, ref, watch } from 'vue';
import { ElMessage } from 'element-plus';
import type {
  CameraGroupListType,
  CameraGroupType,
  Camera,
  CameraInPlay,
} from '@/views/disaster/monitor/splitScreenRetrieval/type';
import {
  queryCameraGroupList,
  addCameraGroupApi,
  deleteCameraGroupApi,
  addCameraIntoGroupApi,
  deleteCameraFromGroupApi,
  modifyCameraGroupApi,
  saveOrUpdateCameraGroupAllApi,
  queryCameraGroupListByTypeAndSourceIdApi
} from '@/api/nine-square-grid';
import { parseCameraGroupChildren } from '@/views/disaster/monitor/splitScreenRetrieval/hooks/parseData';
import { userGridType } from './userGridType';
import { storeToRefs } from 'pinia';
import { CameraStatusDetail } from '@/api/camera/camera';

const { currentGrid } = storeToRefs(userGridType());

export const useCameraGroupList = defineStore('useCameraGroupList', () => {
  const cameraGroupList = ref<CameraGroupListType>([]); // 所有分组列表
  const cameraStatusList = ref<CameraStatusDetail[]>([]); // 相机状态列表
  const playingGroup = ref<CameraGroupType>(); // 正在轮播的分组
  const cameraInPlay = ref<CameraInPlay[]>([]); // 正在轮播中的摄像头列表
  const playIntervalTime = ref<number>(60); // 播放间隔
  const isPlaying = ref<boolean>(false); // 是否正在播放
  const isPaused = ref<boolean>(false); // 播放是否暂停
  const startIndex = ref<number>(0);
  const endIndex = ref<number>(0);
  let timer; // 轮播定时器

  // 轮播分组里的所有摄像头列表
  const carouselList = computed(() => {
    const theGroupAllCameras = (cameraGroupList.value.find((x) => x.id === playingGroup.value?.id)?.children ||
      []) as CameraInPlay[];

    const goodCameras = theGroupAllCameras.filter((x) => {
      // 如果相机cameraStatusList长度为0，说明还未请求数据，这时候先返回所有的相机进行展示。
      if (cameraStatusList.value.length === 0) return true;
      // 如果有坏的相机，这时候要进行过滤掉
      return cameraStatusList.value.find((item) => item.code === x.code)?.networkingState === 0;
    });
    return goodCameras;
  });

  // 总轮数
  const totalRound = computed(() => Math.ceil(carouselList.value.length / currentGrid.value));

  // 当前轮数
  const currentRound = computed(() => {
    // 没有接入相机时
    if (cameraInPlay.value.every((x) => x.url === '')) return 0;

    // 在第一轮时
    if (startIndex.value === 0) return 1;

    return Math.floor((startIndex.value / carouselList.value.length) * totalRound.value + 1);
  });

  // 默认为9宫格
  initialGrid(currentGrid.value);

  function initialGrid(gridNum: number) {
    const tempList: CameraInPlay[] = [];
    for (let i = 1; i < gridNum + 1; i++) {
      tempList.push({
        id: -i, // 负id为用于填充宫格的假摄像头
        cameraGroupDetailId: -i,
        url: '',
        name: '',
        code: '',
        imageUrl: '',
      });
    }
    cameraInPlay.value = tempList;
  }

  function getCameraGroupList(type: number = 0) {
    queryCameraGroupList(type).then((res) => {
      console.log('res', res);

      cameraGroupList.value = parseCameraGroupChildren(res);
      const defaultPlayGroup = cameraGroupList.value.find((x) => x.isDefault === 1);
      if (defaultPlayGroup) {
        isPlaying.value = true;
        playingGroup.value = defaultPlayGroup;

        // 如果分组是默认播放但没设置播放间隔则设置播放间隔为60秒
        if (!defaultPlayGroup.playIntervalSec) defaultPlayGroup.playIntervalSec = 60;

        playIntervalTime.value = defaultPlayGroup?.playIntervalSec;
        isPaused.value = Boolean(defaultPlayGroup?.isPaused);
        groupStartPlay(defaultPlayGroup.playIntervalSec);
      }
    });
  }

  function createCameraGroup(groupName: string) {
    // 由于请求接口有延迟，所以先更新本地数据，然后再通过接口更新数据
    if (cameraGroupList.value.find((x) => x.groupName === groupName))
      return ElMessage({ message: '区域名已存在', type: 'error' });

    const newGroup = {
      id: Date.now(),
      groupName: groupName,
      children: [],
      isDefault: 0,
      playIntervalSec: 0,
      isPaused: false,
    };

    cameraGroupList.value.unshift(newGroup);

    addCameraGroupApi({ groupName })
      .then((res) => {
        // getCameraGroupList();
        newGroup.id = res;
      })
      .catch(() => {
        ElMessage({ message: '新建区域失败', type: 'error' });
      });
  }

  function deleteCameraGroup(id: number) {
    if (id === playingGroup.value?.id) stopPlay(id);

    // 由于请求接口有延迟，所以先更新本地数据，然后再通过接口更新数据
    cameraGroupList.value = cameraGroupList.value.filter((x) => x.id !== id);

    deleteCameraGroupApi(id).then(() => {
      // getCameraGroupList();
    });
  }

  function addCameraIntoGroup(id: number, camera: Camera) {
    const group = cameraGroupList.value.find((x) => x.id === id);
    // 由于请求接口有延迟，所以先更新本地数据，然后再通过接口更新数据
    const newCamera = {
      name: camera.name,
      code: camera.code,
      id: camera.id,
      url: camera.url,
      cameraGroupDetailId: 0,
      imageUrl: camera.imageUrl,
    };
    group?.children.push(newCamera);
    const newCameraToBackEnd = {
      cameraId: camera.id,
      groupId: group!.id,
      orderNum: group!.children.length,
    };
    addCameraIntoGroupApi(newCameraToBackEnd).then((res) => {
      // getCameraGroupList();

      newCamera.cameraGroupDetailId = res.cameraGroupDetailId;
    });

    // group?.children.push(camera);
  }

  function deleteCameraFromGroup(cameraGroup: CameraGroupType, camera: Camera) {
    if (camera.cameraGroupDetailId === 0) {
      return;
    }

    // 由于请求接口有延迟，所以先更新本地数据，然后再通过接口更新数据
    cameraGroup.children = cameraGroup.children.filter((x) => x.id !== camera.id);

    deleteCameraFromGroupApi({
      // cameraGroupDetailId: cameraGroupDetailId!,
      groupId: cameraGroup.id,
      cameraId: camera.id,
    }).then(() => {
      // getCameraGroupList();
    });
  }

  // 删除正在播放的相机
  function deleteCameraInPlaylist(cameraGroup: CameraGroupType, camera: Camera) {
    const newCameraInPlay = cameraInPlay.value.filter((x) => x.id !== camera.id);

    // 如果轮播数只有一轮且摄像头未填充满宫格
    if (getValidateCameraNum() <= currentGrid.value && totalRound.value === 1) {
      deleteCameraFromGroup(cameraGroup, camera);
      restartPlay();
      return;
    }

    // 用于替代被删除相机的相机index
    let replaceCameraIndex: null | number = null;

    // 如果当前是最后一轮
    if (currentRound.value === totalRound.value) {
      // 正在播放的相机列表中最后一个非填充补位的相机的index
      const lastCameraIndex = cameraInPlay.value.findIndex((x) => x.id === carouselList.value.slice(-1)[0].id);

      // 用于填充空屏的相机列表
      const cameraOfFillList = cameraInPlay.value.slice(lastCameraIndex + 1, cameraInPlay.value.length);

      // 如果被删除的相机不在用于填充的相机中，且用于填充的相机等于当前宫格数-1，则表示删除的是最后一个剩余未播放的相机，那么删除该相机后返回第一轮
      if (!cameraOfFillList.includes(camera) && cameraOfFillList.length === currentGrid.value - 1) {
        restartPlay();
        deleteCameraFromGroup(cameraGroup, camera);
        return;
      }
      // 如果删除的是用于填充的相机，则用它在所有播放列表里所在位置的下一个相机代替
      else {
        replaceCameraIndex = carouselList.value.indexOf(cameraOfFillList.slice(-1)[0]) + 1;
      }
    } else {
      // 用当前播放列表里的最后一个相机在所有播放列表里所在位置的下一个相机代替
      replaceCameraIndex = carouselList.value.indexOf(cameraInPlay.value.slice(-1)[0]) + 1;

      // 防止掉线相机重连后让endIndex被推后
      endIndex.value = replaceCameraIndex;
    }
    // 用未播放的相机填充被删除相机
    newCameraInPlay.push(carouselList.value[replaceCameraIndex!]);

    deleteCameraFromGroup(cameraGroup, camera);
    cameraInPlay.value = newCameraInPlay;

    // 更新startIndex避免currentRound出错
    startIndex.value = carouselList.value.indexOf(cameraInPlay.value[0]);
  }

  const updateCameraStatus = (list: CameraStatusDetail[]) => {
    // 比较
    cameraStatusList.value = list;

    // 如果在播的相机掉线，则返回第一轮
    const isAllGood = cameraInPlay.value.every((x) => list.find((item) => item.code === x.code)?.networkingState === 0);
    if (!isAllGood) {
      restartPlay();
    }
  };

  function setPlayGroup(cameraGroup: CameraGroupType) {
    playingGroup.value = cameraGroup;
  }

  function fillEmptyGrid(emptyGrid: number) {
    // // 如果当前轮播列表的摄像头数量不够填满宫格，则往无摄像头的宫格插入id为负的空摄像头
    const tempList: CameraInPlay[] = [];
    for (let i = 1; i < emptyGrid + 1; i++) {
      tempList.push({
        id: -i, // 负id为用于填充宫格的假摄像头
        cameraGroupDetailId: -i,
        url: '',
        name: '',
        code: '',
        imageUrl: '',
      });
    }
    cameraInPlay.value = cameraInPlay.value.concat(tempList);
  }

  // 切换到上一轮的逻辑是把索引设置为上上轮，再立即播放下一轮
  function playPreviousRound() {
    startIndex.value -= 2 * currentGrid.value;
    endIndex.value = startIndex.value + currentGrid.value;
    if (startIndex.value < 0) {
      endIndex.value = 0;
      startIndex.value = 0;
    }
    console.log('previousRound startIndex.value', startIndex.value);
    console.log('previousRound endIndex.value', endIndex.value);
    playNextRound();
  }

  function playNextRound() {
    // 轮播列表摄像头数小于宫格数时停止轮播
    if (carouselList.value.length < currentGrid.value) {
      cameraInPlay.value = carouselList.value;
      const emptyGridNum = currentGrid.value - cameraInPlay.value.length;
      fillEmptyGrid(emptyGridNum);
      return;
    }

    // 如果正好播完分组里的全部摄像头，则直接返回第一轮
    if (endIndex.value === carouselList.value.length) {
      endIndex.value = 0;
      startIndex.value = 0;
    }

    // 即将播放完分组里的全部摄像头时，如果剩余的摄像头数量不能充满宫格，则用分组里index为0到（缺少的数量）的摄像头填充
    if (endIndex.value + currentGrid.value > carouselList.value.length) {
      // 剩余未播放的摄像头
      const restCameras = carouselList.value.slice(endIndex.value, carouselList.value.length + 1);

      endIndex.value = currentGrid.value - restCameras.length;

      // 用于填充的摄像头
      const fillGridCameras = carouselList.value.slice(0, endIndex.value);

      cameraInPlay.value = restCameras.concat(fillGridCameras);

      startIndex.value += currentGrid.value;
      console.log('startIndex.value', startIndex.value);
      console.log('endIndex.value', endIndex.value);

      // 注释掉可改变第二轮开始以及后续轮次的摄像头顺序
      endIndex.value = 0;

      return;
    }
    endIndex.value = endIndex.value + currentGrid.value;
    startIndex.value = endIndex.value - currentGrid.value;

    console.log('startIndex.value', startIndex.value);
    console.log('endIndex.value', endIndex.value);

    cameraInPlay.value = carouselList.value.slice(startIndex.value, endIndex.value);
  }

  function groupStartPlay(intervalTime: number) {
    // 如果正在轮播就清空之前的计时器，避免重复创建多个计时器
    if (isPlaying.value) {
      cleanTimer();
    }

    // 如果先前未在轮播，则在计时器开始前先开始第一次轮播
    if (!cameraInPlay.value.find((x) => x.id > 0)) {
      playNextRound();
    }

    if (isPaused.value === false) {
      timer = setInterval(() => {
        playNextRound();
      }, intervalTime * 1000);
    }
  }

  function cleanTimer() {
    clearInterval(timer);
    timer = null;
  }

  function pausePlay() {
    cleanTimer();
  }

  function stopPlay(id: number, setIsDefault?: boolean) {
    playingGroup.value = undefined;
    cameraInPlay.value = [];
    isPlaying.value = false;
    startIndex.value = 0;
    endIndex.value = 0;
    initialGrid(currentGrid.value);
    cleanTimer();
    if (setIsDefault) {
      modifyCameraGroupApi({
        groupId: id,
        isDefault: 0,
      });
    }
  }

  function continuePlay() {
    playNextRound();
    timer = setInterval(() => {
      playNextRound();
    }, playIntervalTime.value * 1000);
  }

  function restartPlay() {
    endIndex.value = 0;
    startIndex.value = 0;
    // 重置轮次为第一轮后立即开始第一轮轮播
    playNextRound();
    if (isPaused.value === false) {
      groupStartPlay(playIntervalTime.value);
    }
  }

  // 正在播放的宫格中的有效相机数
  function getValidateCameraNum() {
    return cameraInPlay.value.reduce((sum, camera) => (sum += camera.id > 0 ? 1 : 0), 0);
  }


  function saveOrUpdateCameraGroupAll(groupName: string, type: number, sourceId: number | null = null) {
    if (cameraGroupList.value.find((x) => x.groupName === groupName))
      return ElMessage({ message: '区域名已存在', type: 'error' });

    const newGroup = {
      // id: Date.now(),
      groupName,
      type,
      sourceId
      //  children: [],
      // isDefault: 0,
      // playIntervalSec: 0,
      // isPaused: false,
    } as any;

    cameraGroupList.value.unshift(newGroup);


    saveOrUpdateCameraGroupAllApi({...newGroup})
      .then((res) => {
        // getCameraGroupList();
        newGroup.id = res;
      })
      .catch(() => {
        ElMessage({ message: '新建区域失败', type: 'error' });
      });
  }

  function queryCameraGroupListByTypeAndSourceId(type: number = 0, sourceId: number | null = null) {
    queryCameraGroupListByTypeAndSourceIdApi({type, sourceId}).then((res) => {

      cameraGroupList.value = parseCameraGroupChildren(res);
      const defaultPlayGroup = cameraGroupList.value.find((x) => x.isDefault === 1);
      if (defaultPlayGroup) {
        isPlaying.value = true;
        playingGroup.value = defaultPlayGroup;

        // 如果分组是默认播放但没设置播放间隔则设置播放间隔为60秒
        if (!defaultPlayGroup.playIntervalSec) defaultPlayGroup.playIntervalSec = 60;

        playIntervalTime.value = defaultPlayGroup?.playIntervalSec;
        isPaused.value = Boolean(defaultPlayGroup?.isPaused);
        groupStartPlay(defaultPlayGroup.playIntervalSec);
      }
    });
  }

  // 切换宫格时调整正在轮播中的摄像头列表
  watch(
    () => currentGrid.value,
    (newGridNum) => {
      cleanTimer();

      // 如果当前在轮播
      if (cameraInPlay.value.find((x) => x.id > 0)) {
        restartPlay();
      }
      // 如果当前不在轮播
      else {
        initialGrid(newGridNum);
      }
    },
  );

  return {
    carouselList,
    playingGroup,
    cameraGroupList,
    cameraStatusList,
    cameraInPlay,
    isPlaying,
    isPaused,
    playIntervalTime,
    totalRound,
    currentRound,
    getCameraGroupList,
    createCameraGroup,
    deleteCameraGroup,
    addCameraIntoGroup,
    deleteCameraFromGroup,
    deleteCameraInPlaylist,
    setPlayGroup,
    groupStartPlay,
    playPreviousRound,
    playNextRound,
    continuePlay,
    stopPlay,
    pausePlay,
    restartPlay,
    getValidateCameraNum,
    updateCameraStatus,
    saveOrUpdateCameraGroupAll,
    queryCameraGroupListByTypeAndSourceId
  };
});

export default useCameraGroupList;
