import { Injectable, Logger } from '@nestjs/common';
import { CacheService } from 'src/cache/cache.service';

@Injectable()
export class RotateService {
  constructor(private cacheService: CacheService) {}
  private actionRequestPool = {};
  private logger: Logger = new Logger('rotateService');
  private Actions = {
    Clicking: 1,
    Rotation: 1014,
    Joystick: 15,
  };
  private users = {};
  private replies = {};

  init(app_id, userId) {
    const user = {
      appId: null,
      userId: null,
      breakPointId: null,
      roomId: null,
      player: {
        position: { x: -700, y: 0, z: 0 },
        angle: {
          pitch: 0,
          yaw: 0,
          roll: 0,
        },
      },
      camera: {
        position: { x: -1145, y: 0, z: 160 },
        angle: {
          pitch: 0,
          yaw: 0,
          roll: 0,
        },
      },
      rotateInfo: {
        frameIndex: 0,
        horizontal_move: 0,
        mediaSrc: null,
      },
      moveInfo: {},
      // traceIds: [],
      // actionResponses:[]
    };

    user.appId = app_id;
    user.userId = userId;
    user.breakPointId = 100;
    this.users[userId] = user;

    const reply = {
      traceIds: [],
      vehicle: null,
      mediaSrc: null,
      newUserStates: [
        {
          userId: 'dcff36ae4fc1d',
          playerState: {
            roomTypeId: '',
            person: 0,
            avatarId: '',
            skinId: '',
            roomId: '',
            isHost: false,
            isFollowHost: false,
            skinDataVersion: '',
            avatarComponents: '',
            nickName: '',
            movingMode: 0,
            attitude: '',
            areaName: '',
            pathName: '',
            pathId: '',
            avatarSize: 1,
            extra: '',
            prioritySync: false,
            player: {
              position: { x: -700, y: 0, z: 0 },
              angle: {
                pitch: 0,
                yaw: 0,
                roll: 0,
              },
            },
            camera: {
              position: { x: -1145, y: 0, z: 160 },
              angle: {
                pitch: 0,
                yaw: 0,
                roll: 0,
              },
            },
            cameraCenter: { x: -700, y: 0, z: 0 },
          },
          renderInfo: {
            renderType: 0,
            videoFrame: null,
            cameraStateType: 3,
            isMoving: 0,
            needIfr: 0,
            isVideo: 0,
            stillFrame: 0,
            isRotating: 0,
            isFollowing: 0,
            clientPanoTitlesBitmap: [],
            clientPanoTreceId: '',
            prefetchVideoId: '',
            noMedia: false,
          },
          event: null,
          relation: 1,
        },
      ],
      actionResponses: [
        // {
        //     "actionType": 15,
        //     "pointType": 100,
        //     "extra": "",
        //     "traceId": "d0864cd0-378d-4d49-b7b0-3e8e1b9494c3",
        //     "packetId": "d44bd2f5-f877-4dd7-868b-803c64f99082",
        //     "nps": [],
        //     "peopleNum": 0,
        //     "zoneId": "",
        //     "echoMsg": "",
        //     "reserveDetail": null,
        //     "userWithAvatarList": [],
        //     "newUserStates": [],
        //     "code": 0,
        //     "msg": ""
        // }
      ],
      getStateType: 0,
      code: 0,
      msg: 'OK',
    };

    reply['newUserStates'][0]['userId'] = userId;
    this.replies[userId] = reply;
    return reply;
  }

  async rotate(actionRequest) {
    try {
      const userId = actionRequest['user_id'];
      if (this.actionRequestPool[userId]) {
        this.actionRequestPool[userId].push(actionRequest);
      } else {
        this.actionRequestPool[userId] = [];
        this.actionRequestPool[userId].push(actionRequest);
      }

      const reply = this.replies[userId];

      const actionRequests = this.actionRequestPool[userId];
      const user = this.users[userId];
      // debugger;
      let horizontal_move = user.rotateInfo.horizontal_move;
      //const traceIds = user.traceIds;
      let sub = 0;
      for (let i = 0; i < actionRequests.length; ++i) {
        if (actionRequests[i].action_type == this.Actions.Rotation) {
          horizontal_move += actionRequests[i].rotation_action.horizontal_move;
          reply.traceIds.push(actionRequests[i].trace_id);
          const actionResponse = this.createActionResponse(
            actionRequests[i].action_type,
            actionRequests[i].trace_id,
          );
          reply.actionResponses.push(actionResponse);
          ++sub;
        } else {
          break;
        }
      }

      actionRequests.splice(0, sub);
      const hAngle = horizontal_move * 90;
      if (Math.abs(hAngle) < 1) {
        user.rotateInfo.horizontal_move = horizontal_move;
        //user.traceIds = traceIds;
        this.replies[userId] = reply;
        return null;
      }
      return this.rotateForAngle(userId, hAngle);
      /*
      user.rotateInfo.frameIndex += Math.floor(hAngle);
      if (user.rotateInfo.frameIndex < 0) {
        user.rotateInfo.frameIndex = 360 - user.rotateInfo.frameIndex;
      } else if (user.rotateInfo.frameIndex > 359) {
        user.rotateInfo.frameIndex -= 360;
      }
      reply['traceIds'] = traceIds;
      reply['newUserStates'][0]['userId'] = userId;
      //从redis里取
      //let key = user.appId + "-"+user.breakPointId+"-"+user.rotateInfo.frameIndex;
      const key =
        'rotateframe:app_id:' +
        user.appId +
        ':frame_index:' +
        user.rotateInfo.frameIndex +
        ':break_point_id:' +
        user.breakPointId;
      // const value = null;

      const redisData = await this.cacheService.get(key);
      const value = JSON.parse(redisData);
      console.log('redis', value);
      user.camera['position'] = value ? value.cameraPosition : '';
      user.camera['angle'] = value ? value.cameraAngle : '';

      //this.reply['newUserStates'][0]['playerState'] .player
      reply['newUserStates'][0]['playerState'].camera.position =
        user.camera['position'];
      reply['newUserStates'][0]['playerState'].camera.angle =
        user.camera['angle'];
      reply['newUserStates'][0]['playerState'].cameraCenter =
        user.player.position;
      // debugger
      reply.mediaSrc =
        '/' +
        '0000000001' +
        '/' +
        user.breakPointId +
        '/' +
        value.directory +
        '/' +
        value.fileName +
        '?m=' +
        new Date().getTime();

      this.replies[userId].traceIds = [];
      this.replies[userId].actionResponses = [];

      return reply;
      */
    } catch (error) {
      console.log('RotateService', error);
    }
  }

  async rotateForAngle(userId, hAngle) {
    try {
      const user = this.users[userId];
      user.rotateInfo.frameIndex += Math.floor(hAngle);
      if (user.rotateInfo.frameIndex < 0) {
        user.rotateInfo.frameIndex = 360 - user.rotateInfo.frameIndex;
      } else if (user.rotateInfo.frameIndex > 359) {
        user.rotateInfo.frameIndex -= 360;
      }

      const reply = JSON.parse(JSON.stringify(this.replies[userId]));
      reply['newUserStates'][0]['userId'] = userId;
      //从redis里取
      //let key = user.appId + "-"+user.breakPointId+"-"+user.rotateInfo.frameIndex;
      const key =
        'rotateframe:app_id:' +
        user.appId +
        ':frame_index:' +
        user.rotateInfo.frameIndex +
        ':break_point_id:' +
        user.breakPointId;
      // const value = null;

      const redisData = await this.cacheService.get(key);
      if (redisData && redisData.length > 0) {
        const value = redisData ? JSON.parse(redisData) : null;
        console.log('rotate-service', value);
        user.camera['position'] = value ? value.cameraPosition : '';
        user.camera['angle'] = value ? value.cameraAngle : '';

        reply['newUserStates'][0]['playerState'].player.position =
          user.player.position;
        reply['newUserStates'][0]['playerState'].player.angle =
          user.player.angle;

        //this.reply['newUserStates'][0]['playerState'] .player
        reply['newUserStates'][0]['playerState'].camera.position =
          user.camera['position'];
        reply['newUserStates'][0]['playerState'].camera.angle =
          user.camera['angle'];
        reply['newUserStates'][0]['playerState'].cameraCenter =
          user.player.position;
        // debugger
        reply.mediaSrc =
          '/' +
          '0000000001' +
          '/' +
          user.breakPointId +
          '/' +
          value.directory +
          '/' +
          value.fileName +
          '?m=' +
          new Date().getTime();

        this.replies[userId].traceIds = [];
        this.replies[userId].actionResponses = [];

        user.rotateInfo.horizontal_move = 0;

        return reply;
      } else {
        return null;
      }
    } catch (error) {
      this.logger.error('rotateForAngle::function', error);
    }
  }

  createActionResponse(actionType, traceId) {
    const actionResponse = {
      actionType: actionType,
      pointType: 100,
      extra: '',
      traceId: traceId,
      packetId: '',
      nps: [],
      peopleNum: 0,
      zoneId: '',
      echoMsg: '',
      reserveDetail: null,
      userWithAvatarList: [],
      newUserStates: [],
      code: 0,
      msg: '',
    };
    return actionResponse;
  }

  getNewUserStateRequest(actionRequest) {
    try {
      const userId = actionRequest['user_id'];
      const actionType = actionRequest['action_type'];
      const traceId = actionRequest['trace_id'];

      const reply = {
        actionType: actionType,
        pointType: 100,
        extra: '',
        traceId: traceId,
        packetId: '',
        nps: [],
        peopleNum: 0,
        zoneId: '',
        echoMsg: '',
        reserveDetail: null,
        userWithAvatarList: [],
        newUserStates: [],
        code: 0,
        msg: '',
      };

      const userIds = Object.keys(this.users);
      for (let i = 0; i < userIds.length; ++i) {
        const _user = this.users[userIds[i]];
        const newUserState = {
          userId: userIds[i],
          playerState: {
            roomTypeId: '',
            person: 0,
            avatarId: 'KGe_Boy',
            skinId: '10089',
            roomId: 'e629ef3e-022d-4e64-8654-703bb96410eb',
            isHost: false,
            isFollowHost: false,
            skinDataVersion: '1008900008',
            avatarComponents: '',
            nickName: userIds[i],
            movingMode: 0,
            attitude: 'walk',
            areaName: '',
            pathName: 'thirdwalk',
            pathId: 'thirdwalk',
            avatarSize: 1,
            extra: '{"removeWhenDisconnected":true}',
            prioritySync: false,
            player: {
              position: _user.player.position,
              angle: _user.player.angle,
            },
            camera: null,
            cameraCenter: null,
          },
          renderInfo: {
            renderType: 0,
            videoFrame: null,
            cameraStateType: 0,
            isMoving: 0,
            needIfr: 0,
            isVideo: 0,
            stillFrame: 0,
            isRotating: 0,
            isFollowing: 0,
            clientPanoTitlesBitmap: [],
            clientPanoTreceId: '',
            prefetchVideoId: '',
            noMedia: false,
          },
          event: {
            id: '',
            type: 0,
            points: [],
            rotateEvent: null,
            removeVisitorEvent: null,
          },
          relation: 0,
        };

        reply['newUserStates'].push(newUserState);
      }

      return reply;
    } catch (error) {
      this.logger.error('getNewUserStateRequest::function', error);
    }
  }

  async echo(userId) {
    const user = this.users[userId];
    const reply = JSON.parse(JSON.stringify(this.replies[userId]));
    reply['newUserStates'][0]['userId'] = userId;
    reply['newUserStates'][0]['playerState'].player.position =
      user.player.position;
    reply['newUserStates'][0]['playerState'].player.angle = user.player.angle;
    reply['newUserStates'][0]['playerState'].camera.position =
      user.camera['position'];
    reply['newUserStates'][0]['playerState'].camera.angle =
      user.camera['angle'];
    reply['newUserStates'][0]['playerState'].cameraCenter =
      user.player.position;

    const key =
      'rotateframe:app_id:' +
      user.appId +
      ':frame_index:' +
      user.rotateInfo.frameIndex +
      ':break_point_id:' +
      user.breakPointId;
    const redisData = await this.cacheService.get(key);
    if (redisData && redisData.length > 0) {
      const value = redisData ? JSON.parse(redisData) : null;
      reply.mediaSrc =
        '/' +
        '0000000001' +
        '/' +
        user.breakPointId +
        '/' +
        value.directory +
        '/' +
        value.fileName +
        '?m=' +
        new Date().getTime();
      return reply;
    } else {
      return null;
    }
  }
}
