import {
  defineComponent,
  reactive,
  PropType,
  onMounted,
  watchEffect,
  watch,
  computed,
} from 'vue';
import { useRoute, useRouter } from 'vue-router';
import isString from 'lodash/isString';
import useMarkerStore, { MarkerType } from '@/store/useMarkerStore';
import MapView from '../MapView';
import { useDaHuaStore } from '@/store';

/** @ts-ignore */
import icon_map_yjcl from '@/assets/icons/home/yjcl.svg';
/** @ts-ignore */
import icon_map_yjsj from '@/assets/icons/home/yjsj.svg';
/** @ts-ignore */
import icon_map_yjdw from '@/assets/icons/home/yjdw.svg';
/** @ts-ignore */
import icon_map_yjdw_w from '@/assets/icons/home/icon_map_yjdw_w.svg';
/** @ts-ignore */
import icon_map_yjck from '@/assets/icons/home/yjck.svg';
/** @ts-ignore */
import icon_map_yjck_w from '@/assets/icons/home/icon_map_yjck_w.svg';
/** @ts-ignore */
import icon_map_spjk from '@/assets/icons/home/spjk.svg';
/** @ts-ignore */
import icon_map_dcz from '@/assets/icons/home/icon_map_dcz.svg';
/** @ts-ignore */
import icon_map_dpf from '@/assets/icons/home/dpf.svg';
/** @ts-ignore */
import icon_map_dbsb from '@/assets/icons/home/dbsb.svg';

import './index.scss';
import {
  GET_INCIDENT_DIALOG_HTML,
  GET_TEAM_DIALOG_HTML,
  GET_VEHICLES_DIALOG_HTML,
  GET_VIDEO_DIALOG_HTML,
  GET_WAREHOUSE_DIALOG_HTML,
  GET_SINGLE_DEVICE_DIALOG_HTML,
  renderElement,
} from './dialog';
import { IncidentItemDetail } from '@/api/incident';
import { useIncidentStore } from '@/store';
import Popup from '../Popup';
import { ElMessage } from 'element-plus';
import { isEmpty } from 'lodash';
import clsx from 'clsx';
import { SingleDeviceItem } from '@/api/resource';

const MARKER_MAP_TYPES = [
  // '待派发事件',
  // '待处置事件',
  '路况信息',
  '视频监控',
  '应急车辆',
  '应急队伍',
  '应急仓库',
  '应急事件',
  '单兵',
] as const;

export type MarkerMapType = typeof MARKER_MAP_TYPES[number];

interface State {
  map: any;
  types: MarkerMapType[];
  trafficLayerIds: any[];
  timer?: NodeJS.Timer | null;
  trafficStatus: boolean;
  markers: MarkerType[];
  positions: string[];
  hasTypes: string[];
  // theSocket: null;
}

interface ActionType {
  type: MarkerMapType;
  hasActioned: boolean;
  action: Function;
  remove: Function;
}

// locationType + resourceType
const RESOURCE_ICON_MAP = {
  '11': icon_map_yjck_w, // 水上 仓库
  '21': icon_map_yjck, // 陆上 仓库
  '12': icon_map_yjdw_w, // 水上 队伍
  '22': icon_map_yjdw, // 陆上 队伍
  '13': icon_map_yjcl, // 水上 车辆
  '23': icon_map_yjcl, // 陆上 车辆
};

const getResourceIcon = (locationType: string, resourceType: string) => {
  // @ts-ignore
  return RESOURCE_ICON_MAP[locationType + resourceType] || '';
};

// 路况信息刷新间隔
const REFRESH_TRAFFIC_TIME = 60000;

// let theSocket = null;

// let vPlayArea =null;

const getIncidentImage = (status: MarkerType['status']) =>
  status?.toString() === '1'
    ? icon_map_yjsj
    : status?.toString() === '2'
    ? icon_map_dpf
    : status?.toString() === '3'
    ? icon_map_dcz
    : icon_map_yjsj;

export default defineComponent({
  name: 'MarkerMap',
  props: {
    adrsMapTypes: {
      type: Array as PropType<string[]>,
      default: MARKER_MAP_TYPES,
    },
    marker: Object as PropType<IncidentItemDetail | undefined | null>,
    readonly: Boolean,
  },
  setup(props, ctx) {
    const state = reactive<State>({
      map: null,
      types: [],
      trafficLayerIds: [],
      timer: undefined,
      trafficStatus: false,
      markers: [],
      positions: [],
      hasTypes: [],
      // theSocket:null
    });

    const store = useMarkerStore();
    const incidentStore = useIncidentStore();
    const daHuaStore = useDaHuaStore();
    const router = useRouter();
    const route = useRoute();
    // const theSocket = null;

    const adrsMapTypes = computed(() =>
      props.adrsMapTypes.map((i) => ({
        name: i,
        disabled: route.query.id && i === '应急事件',
      })),
    );

    const actionTypes = computed<ActionType[]>(() => [
      {
        type: '路况信息',
        hasActioned: state.trafficStatus,
        action: toggleControlTraffic,
        remove: toggleControlTraffic,
      },
      {
        type: '应急事件',
        hasActioned: state.hasTypes.includes('应急事件'),
        action: () =>
          handleAddMarkers('应急事件', store.incident, icon_map_dpf),
        remove: () => handleRemoveMarkers('应急事件', store.incident),
      },

      {
        type: '视频监控',
        hasActioned: state.hasTypes.includes('视频监控'),
        action: () =>
          // console.log(store.videoSurveillance);
          handleAddMarkers('视频监控', store.videoSurveillance, icon_map_spjk),
        remove: () => handleRemoveMarkers('视频监控', store.videoSurveillance),
      },
      {
        type: '应急车辆',
        hasActioned: state.hasTypes.includes('应急车辆'),
        action: () =>
          handleAddMarkers('应急车辆', store.emergencyVehicles, icon_map_yjcl),
        remove: () => handleRemoveMarkers('应急车辆', store.emergencyVehicles),
      },
      {
        type: '应急队伍',
        hasActioned: state.hasTypes.includes('应急队伍'),
        action: () =>
          handleAddMarkers('应急队伍', store.emergencyTeam, icon_map_yjdw),
        remove: () => handleRemoveMarkers('应急队伍', store.emergencyTeam),
      },
      {
        type: '应急仓库',
        hasActioned: state.hasTypes.includes('应急仓库'),
        action: () =>
          handleAddMarkers('应急仓库', store.emergencyWarehouse, icon_map_yjck),
        remove: () => handleRemoveMarkers('应急仓库', store.emergencyWarehouse),
      },
      {
        type: '单兵',
        hasActioned: state.hasTypes.includes('单兵'),
        action: () =>
          handleAddMarkers('单兵', store.singleDevice, icon_map_dbsb),
        remove: () => handleRemoveMarkers('单兵', store.singleDevice),
      },
    ]);

    const getMarkerPopupHTML = (type: MarkerMapType, marker: MarkerType) => {
      switch (type) {
        case '应急事件':
        // case '待派发事件':
        // case '预警事件':
        default:
          return GET_INCIDENT_DIALOG_HTML(marker, async () => {
            marker.id && (await incidentStore.getIncidentItem(marker.id));
            await router.push(`/incidentDetail?id=${marker?.id}`);
            handleSetDetailMarker(marker);
            store.currentIncident = marker;
          });
        case '单兵': {
          var callback = () => {
            console.log(marker['deviceCode']);
            console.log(marker['userId']);
            // daHuaStore.DAHUAUserObj(marker["userId"]).then(deviceUser=>{
            //              console.log(deviceUser);
            //              let memberObj = {
            //                     userName:deviceUser.userName,
            //                     userId:deviceUser.userCode,
            //                     region:deviceUser.paasId,
            //                     type:'single',
            //                     // speak:'true',
            //                     number:deviceUser.userPhone,
            //                     deviceId:marker["deviceCode"],
            //                     channelId:marker["channelId"],
            //              }
            //              let meetObj = JSON.parse(localStorage.getItem('meeting'));
            //              let memberList = [];
            //              memberList.push(meetObj.member==null||meetObj.member==undefined?"":meetObj.member[0]);
            //              memberList.push(memberObj);
            //              meetObj.member = memberList
            //              console.log(meetObj);
            //              daHuaStore.DAHUAMeetingMember(meetObj).then(data=>{
            //                       //  console.log(11111111)
            //                        daHuaStore.DAHUAMeetingUser(meetObj.meetId);
            //                       daHuaStore.DAHUAUserInfo().then(u => {
            //                         console.log(u,'+++++++');    
            //                         initSocket(u.userCode,memberObj);
            //                       })
            //              })
                         
                        //  console.log(memberObj);
                        //  meetObj.mebmber.push(memberObj);

            const DAHUA = document.getElementById('DAHUA') as HTMLIFrameElement;
            DAHUA?.contentWindow?.postMessage(
              {
                key: 'danbing',
                value: marker['userId'],
                deviceId: marker['deviceCode'],
                channelId: marker['channelId'],
              },
              '*',
            );
            daHuaStore.dahuaUserVisible = true;

            // console.log(daHuaStore.deviceUser);
          };
          return GET_SINGLE_DEVICE_DIALOG_HTML(
            marker as SingleDeviceItem,
            callback,
          );
        }

        case '应急仓库':
          return GET_WAREHOUSE_DIALOG_HTML(marker);
        case '应急车辆':
          return GET_VEHICLES_DIALOG_HTML(marker);
        case '应急队伍':
          return GET_TEAM_DIALOG_HTML(marker);

        case '视频监控':
          return GET_VIDEO_DIALOG_HTML(marker, () => {
            if(marker['status'] == 1){
              const DAHUA = document.getElementById('DAHUA') as HTMLIFrameElement;
              DAHUA?.contentWindow?.postMessage(
                {
                  key: 'video',
                  value: marker['userId'],
                  deviceId: marker['deviceCode'],
                  channelId: marker['channelId'],
                },
                '*',
              );
              daHuaStore.dahuaUserVisible = true;
            }else{
              ElMessage.warning('设备离线，请联系大华相关人员');
            }
          });
      }
    };

    const videoplay = (item: { type: string; userId: any; channelId: any }) => {
      console.log('播放视频');
      console.log(item);
      if (!window.theSocket.websocket) {
        ElMessage.warning('请先打开视频插件');
        return;
      }
      if (item.type == 'client') {
        window.slectOptionmini(item.userId).then((arr: any) => {
          if (arr) {
            window.vPlayArea.openAppVideo(arr);
          }
        });
      } else if (item.type == 'single') {
        //播放单兵视频
        pullFlow(item.channelId);
      } else if (item.type == 'vehicle') {
        //播放车载视频
        pullFlow(item.channelId);
      } else if (item.type == 'uav_dev') {
        //播放无人机视频
        pullFlow(item.channelId);
      }
    };

    const pullFlow = (channelId: any) => {
      channelId &&
        window.vPlayArea &&
        window.vPlayArea.realTimeVideo([{ channelId }]);
    };

    const initSocket = (
      userCode: string,
      memberObj: {
        userName?: any;
        userId: any;
        region?: any;
        type: string;
        number?: any;
        deviceId?: any;
        channelId: any;
      },
    ) => {
      const self = this;
      console.log(userCode);
      localStorage.setItem('userId', userCode);
      //初始websocket实例，保存在window中方便调用。一个浏览器tab页面只能初始化一次。所有的控件窗口，通过该websocket实例去生成不同的窗口实例，不同的控件窗口通过自己的窗口实例去调用初始化、关闭、隐藏等
      window.theSocket = new window.InitWebSocketClass(
        userCode,
        localStorage.getItem('DAHUA_token'),
        {
          //客户端登陆成功通知;
          loginSuccess: (v: any) => {
            console.log(2222222222222222);
            console.log('loginSuccess-->', v);
            initWnd();
          },
          //客户端窗口被拉起通知
          onCreateVideoSuccess: (v: any) => {
            console.log('客户端onCreateVideoSuccess-----', v);
          },
          //重点:统一分发客户端ws消息;vue 可以统一用$bus分发.第三方消息分发自定
          onSocketBackInfos: (data: {
            method: string;
            params: { result: number; handleName: string };
          }) => {
            //视频窗口创建成功通知
            if (
              data &&
              data.method === 'createVideoDialogReuslt' &&
              data.params.result === 0
            ) {
              if (data.params.handleName === '#vPlayArea') {
                //客户端窗口创建好后,界面显示窗口;
                window.vPlayArea.resize();
                ElMessage.warning('视频窗口创建成功！');
                videoplay(memberObj);
              }
            }
          },
        },
      );
      // console.log(theSocket);
      //socket实例初始化websocket回调方法;
      window.theSocket
        .initWebSocket()
        .then((v: any) => {
          if (v) {
            ElMessage.warning('视频插件登陆完成!');
          }
        })
        .catch(() => {
          ElMessage.warning('若要观看实时视频，请先安装视频插件');
        });
    };

    const initWnd = () => {
      console.log(1111);
      //左边窗口类型参数 分割 2行2列
      const typeObj = {
        rows: 2,
        cols: 2,
        wndSpaceing: 10,
        embedVideoMode: true,
        playerCtrlBarEnable: false,
        displayMode: 0,
        playMode: 0,
        playParams: {},
      };
      //左边窗口实例
      window.vPlayArea = new window.VideoPlay(
        '#vPlayArea',
        window.theSocket.websocket, //一个浏览器tab页面公用一个
        window.theSocket.socketCode, //一个浏览器tab页面公用一个
        typeObj,
      );
      //左边窗口初始化
      window.vPlayArea.init();
    };

    const updateTrafficSource = () => {
      if (state.map.getSource('Traffic')) {
        state.map.removeSource('Traffic');
      }
      state.map.addSource('Traffic', {
        type: 'vector',
        traffic: true,
        tiles: [
          'mineserver://data/dynamic-traffic/ertic?servicetype=0&z={z}&x={x}&y={y}',
        ],
      });
    };
    const updateTrafficLayerVisibility = (v: 'none' | 'visible') => {
      state.trafficLayerIds.forEach(function (id) {
        if (state.map?.getLayer(id)) {
          state.map?.setLayoutProperty(id, 'visibility', v);
        }
      });
    };
    const toggleControlTraffic = () => {
      if (state.trafficStatus) {
        state.trafficStatus = false;
        if (state.timer) {
          clearInterval(state.timer);
          state.timer = null;
        }
        updateTrafficLayerVisibility('none');
      } else {
        state.trafficStatus = true;
        if (state.timer) {
          clearInterval(state.timer);
          state.timer = null;
        }
        updateTrafficSource();
        state.timer = setInterval(function () {
          updateTrafficSource();
        }, REFRESH_TRAFFIC_TIME);
        updateTrafficLayerVisibility('visible');
      }
    };
    const handleAddMarkers = (
      type: MarkerMapType,
      markers: State['markers'],
      image: any,
    ) => {
      console.log(state.markers);
      state.markers.push(
        ...markers.map((i) => {
          const nextImage =
            type === '应急事件'
              ? getIncidentImage(i?.status)
              : i.locationType && i.resourceType
              ? getResourceIcon(
                  i.locationType.toString(),
                  i.resourceType.toString(),
                )
              : image;
          const popup = new window.minemap.Popup({
            anchor: 'left',
            closeOnClick: true,
            closeButton: false,
            offset: [10, 25],
            maxWidth: 'max-content',
            // autoPan: true,
          }).setDOMContent(getMarkerPopupHTML(type, i));
          return {
            locations: i.locations,
            popup,
            marker:
              i.locations &&
              new window.minemap.Marker(renderElement(nextImage), {
                offset: [-25, -25],
              })
                .setLngLat({
                  lng: i.locations?.split(',')[0],
                  lat: i.locations?.split(',')[1],
                })
                .setPopup(popup)
                .addTo(state.map),
          };
        }),
      );
      state.positions.push(...markers.map((i) => i.locations).filter(isString));

      handleFitBounds();
    };
    const handleFitBounds = () => {
      if (state.positions.length === 0) {
        return;
      }

      const locations = state.positions.map((i) => i.split(',').map(Number));

      const leftTop = locations.reduce((carry, next) => {
        if (carry.length === 0) return next;
        return [Math.min(carry[0], next[0]), Math.max(carry[1], next[1])];
      }, []);

      const rightBottom = locations.reduce((carry, next) => {
        if (carry.length === 0) return next;
        return [Math.max(carry[0], next[0]), Math.min(carry[1], next[1])];
      }, []);

      const leftTopBounds: number[][] = new window.minemap.LngLat(...leftTop)
        .toBounds(5000)
        .toArray();

      const rightBottomBounds: number[][] = new window.minemap.LngLat(
        ...rightBottom,
      )
        .toBounds(5000)
        .toArray();

      state.map.fitBounds([
        rightBottomBounds.reduce((carry, next) => {
          if (carry.length === 0) return next;
          return [Math.max(carry[0], next[0]), Math.min(carry[1], next[1])];
        }, []),
        leftTopBounds.reduce((carry, next) => {
          if (carry.length === 0) return next;
          return [Math.min(carry[0], next[0]), Math.max(carry[1], next[1])];
        }, []),
      ]);
    };
    const handleRemoveMarkers = (
      type: MarkerMapType,
      markers: State['markers'],
    ) => {
      state.hasTypes = state.hasTypes.filter((t) => t !== type);

      const locations = markers.map((i) => i.locations);
      state.markers.forEach((m) => {
        if (locations.includes(m.locations)) {
          m.marker?.remove();
          m.popup?.remove();
          m.popup = null;
          m.marker = null;
        }
      });
      state.markers = state.markers.filter(
        (m) => !locations.includes(m.locations),
      );
      state.positions = state.positions.filter((p) => !locations.includes(p));

      handleFitBounds();
    };
    const handleRemoveAllMarkers = () => {
      state.markers.forEach((m) => {
        m.marker?.remove();
        m.popup?.remove();
      });
      state.markers = [];
      state.positions = [];
    };

    const handleSetDetailMarker = (marker: MarkerType) => {
      handleRemoveAllMarkers();
      const locations = marker.locations?.split(',').map(Number);

      if (!locations) {
        ElMessage.error({ message: '该点位无地址经纬度' });
        return;
      }

      // 获取事件周围的 5km 内的 监控点
      const bounds: number[][] = new window.minemap.LngLat(...locations)
        .toBounds(10000)
        .toArray();

      const videos = store.videoSurveillance.reduce((carry, next) => {
        const [lng, lat] = next.locations?.split(',') ?? [];
        // bounds [right-bottom[lng, lat],left-top[lng, lat], ]
        if (
          Number(lng) > bounds[0][0] &&
          Number(lng) < bounds[1][0] &&
          Number(lat) > bounds[0][1] &&
          Number(lat) < bounds[1][1]
        ) {
          carry.push(next);
        }
        return carry;
      }, [] as MarkerType[]);

      // 开启路况信息
      if (!state.types.includes('路况信息')) {
        state.types.push('路况信息');
        state.hasTypes.push('路况信息');
        toggleControlTraffic();
      }

      handleAddMarkers('应急事件', [marker], icon_map_dpf);
      handleAddMarkers('视频监控', videos, icon_map_spjk);
      // state.markers[0].marker.togglePopup();
    };

    onMounted(async () => {
      window.minemap.util.getJSON(
        'http://61.147.254.211:21009/service/solu/style/id/12878',
        function (error, data) {
          data.layers.forEach(function (layer: any) {
            //判断是否道路线图层
            if (
              layer.type == 'line' &&
              layer.source == 'Traffic' &&
              layer['source-layer'] == 'Trafficrtic'
            ) {
              state.trafficLayerIds.push(layer.id);
            }
          });
        },
      );
      try {
        const html = document.createElement("div");
        actionTypes.value.forEach(atypes => {
          if (atypes?.action == null) return;
          const name = atypes.type;
          const c = (atypes?.action?.toString().split("handleAddMarkers"));
          if (c.length <= 1) return;
          const args1 = c[1].replaceAll("(","").replaceAll(")","");
          // debugger
          const args = args1.split(",");
         
          if (eval(args[2]) == undefined) return;
          const div = document.createElement("div");
          div.className = "tipitem"

          const imagee = renderElement((eval(args[2])));
          div.append(imagee);
          const c1 = document.createElement("span"); c1.innerHTML = (name);
          div.append(c1);
          html.append(div);
          
        });
        state.map["tipcontentRef"].append(html);
      } catch (ee) {

      }

      state.map.on('load', function () {
        updateTrafficSource();
        //如果底图没有配置路况图层，需要自己手动增加
        state.map.addLayer({
          id: 'trafficlines',
          type: 'line',
          source: 'Traffic',
          'source-layer': 'Trafficrtic',
          layout: {
            'line-join': 'round',
            'line-cap': 'round',
          },
          paint: {
            'line-color': {
              property: 'status',
              stops: [
                [0, '#999999'],
                [1, '#66cc00'],
                [2, '#ff9900'],
                [3, '#cc0000'],
                [4, '#9d0404'],
              ],
            },
            'line-width': {
              stops: [
                [5, 1],
                [18, 3],
              ],
              base: 1.2,
            },
          },
        });

        state.trafficLayerIds.push('trafficlines');
        state.trafficStatus = false;
        updateTrafficLayerVisibility('none');

        store.getAllResources();
        store.getAllsingleDevice();
        store.getAllvideoDevice();
        store.getHDIncidentList();
      });
      if (!route.query.id) return;
      // 如果存在id
      await incidentStore.getIncidentItem(route.query.id as string);
      // @ts-ignore
      handleSetDetailMarker(incidentStore.incidentDetail.baseInfo ?? {});

      // const vPlayAreaEl = document.getElementById('vPlayArea');

      // vPlayAreaEl &&
        // (vPlayAreaEl.style.height = window.innerHeight - 20 + 'px');
      // window.theSocket && window.theSocket.resize();
    });

    watch(
      () => store?.currentIncident,
      (next) => {
        if (!isEmpty(next)) {
          handleSetDetailMarker({
            ...next,
          });
        } else {
          handleRemoveAllMarkers();
          if (state.types.includes('应急事件')) {
            state.types.forEach((next) => {
              actionTypes.value.forEach((item) => {
                if (next === item.type) {
                  state.hasTypes.push(item.type);
                  item.action();
                }
              });
            });
          } else {
            state.map?.flyTo({
              center: [118.29564, 33.97441],
              zoom: 14,
              bearing: 10,
              pitch: 30,
              duration: 2000,
            });
          }
        }
      },
    );

    watch(
      () => state.types,
      (next) => {
        actionTypes.value.forEach((item) => {
          if (next.includes(item.type) && !item.hasActioned) {
            state.hasTypes.push(item.type);
            item.action();
          }
          if (!next.includes(item.type) && item.hasActioned) {
            item.remove();
          }
        });
      },
    );

    return () => (
      <div class="task-map-container">
        <MapView v-model:map={state.map} />
        {/* <div style="width:35%;height:20%;background-color:blue"> */}
        {/*<div id='vPlayArea'  style="width:30%;"/>*/}
        {/* </div> */}

        <div
          class={clsx('address-type-card-container', {
            ['in-detail']: props.readonly,
          })}>
          <Popup
            class={clsx('address-type-card', {
              ['in-detail']: props.readonly,
            })}>
            <el-checkbox-group v-model={state.types}>
              {adrsMapTypes.value &&
                adrsMapTypes.value?.map((t) => (
                  <>
                    {!t.disabled && (
                      <el-checkbox key={t} class="card-item" label={t.name} />
                    )}
                  </>
                ))}
            </el-checkbox-group>
            <i class="card-border-bottom-left"></i>
            <i class="card-border-bottom-right"></i>
          </Popup>
        </div>
      </div>
    );
  },
});
