import data from '../../data.json';
import Wall from './walls/wall';
import wallSafe from './walls/wall_safe';
import wallDanger from './walls/wall_danger'
import Ninya from './ninya';
import Phaser from 'phaser';
import Layout from '../../display/layout.js';

const TILE_SIZE = 64;
const WALL_WIDTH = 12;
const VIEW_WIDTH = 960;
const COLLISION_PRECISION = 2;

export default class map extends Phaser.Group {

  constructor(game, parent, name, view) {
    super(game, parent, name);
    this.view = view;
    this.player;
    this.walls = [];
    this.isHoldingHands = false;
    this.lastWall = false;
    this.overlapping = false;
    this.createGirlGrp();

    // Physics
    this.game.physics.startSystem(Phaser.Physics.ARCADE);
    this.game.myEvents.onWallCollision.add(this.wallCollission, this);
  }

  createMap(level) {
    const lvlData = this.lvlData = data[level];
    const wallsGrp = this.wallsGrp = this.game.add.group(this);
    wallsGrp.enableBody = true;
    wallsGrp.physicsBodyType = Phaser.Physics.ARCADE;

    lvlData.walls.forEach(wall => {
      const wallSpr = this.createWall(wall);
      wallSpr.body.immovable = true;
      wallSpr.body.allowGravity = false;
    });
  }

  wallCollission(isSafe) {
    if (isSafe) {
      // this.isHoldingHands = false;
      this.inputUp();
    }
  }

  createGirlGrp() {
    const ninjaGrp = this.ninjaGrp = this.game.add.group();
    ninjaGrp.enableBody = true;
    ninjaGrp.physicsBodyType = Phaser.Physics.ARCADE;
    this.add(ninjaGrp);
    ninjaGrp.position.set(TILE_SIZE * 5, TILE_SIZE * 4)
    const finger = this.finger = this.game.add.graphics(0, 0);
    // finger.alpha = 0;
    finger.beginFill(0xFF0000, 0.2);
    finger.drawCircle(0, 0, 100);
    ninjaGrp.add(finger);

    const ninya = this.ninya = new Ninya(this.game, 0, 0);
    this.player = ninya;
    ninjaGrp.add(ninya);

    const frames = Phaser.Animation.generateFrameNames('ninya', 1, 4, '.png', 1);
    ninya.animations.add('run', frames, 12, true);

    this.game.myEvents.onCinematicEnd.add(() => {
      finger.inputEnabled = true;
      finger.events.onInputDown.add(() => this.inputDown());
      finger.events.onInputUp.add(() => this.inputUp());
      this.game.myEvents.onGirlDrop.dispatch(this.finger);

      finger.events.onInputDown.addOnce(() => { 
        this.game.myEvents.onGameInputBegin.dispatch();
        this.parent.firstTouch = true;
      }, this);
    });

    this.createHitBox();
    this.game.physics.arcade.enable(this.hitbox);

    // this.hitbox.body.maxVelocity.x *= 100;
    // this.hitbox.body.maxVelocity.y *= 100;
  }

  createHitBox() {
    let x0 = -(this.ninya.width * this.ninya.anchor.x);
    let y0 = -(this.ninya.height * this.ninya.anchor.y);

    const graphics = this.game.add.graphics(x0 + this.ninya.width * 0.35, y0 + this.ninya.height * 0.35);
    graphics.beginFill(0x00000);
    graphics.drawRect(0, 0, this.ninya.width * 0.35, this.ninya.height * 0.60);
    graphics.endFill();
    this.hitbox = this.game.add.sprite(graphics.x, graphics.y, graphics.generateTexture());
    this.hitbox.alpha = 0;
    this.ninjaGrp.add(this.hitbox);
  }


  createWall(wallData) {
    const startCord = this.gridToCoord(wallData.start);
    const endCord = this.gridToCoord(wallData.end);

    let wallGraphics = this.game.add.graphics(startCord.x, startCord.y);
    wallGraphics.beginFill(0xffffff);
    wallGraphics.lineStyle(WALL_WIDTH, 0xffffff, 1);
    wallGraphics.lineTo(endCord.x - startCord.x, endCord.y - startCord.y);
    wallGraphics.endFill();

    const wallSprite = new wallSafe(this.game, 0, 0, wallGraphics.generateTexture());
    wallSprite.position.set(wallGraphics.x - wallGraphics.lineWidth, wallGraphics.y - wallGraphics.lineWidth);
    wallGraphics.destroy();
    // wallSprite.alpha = 0;
    this.wallsGrp.add(wallSprite);

    this.walls.push(wallSprite);
    return wallSprite;
  }

  render() {
    this.game.debug.body(this.hitbox);
    this.game.debug.physicsGroup(this.wallsGrp);
  }

  onResize() {
    this.hitbox.body.setSize(this.hitbox.width * this.view.scale.x, this.hitbox.height * this.view.scale.y);

    this.walls.forEach(wall => {
      wall.body.setSize(wall.width * this.view.scale.x, wall.height * this.view.scale.y);
    })

  }

  update() {
    this.overlapping = false;
    this.lastWall; // If remove, it breaks, boh
    if (this.lastWall) {
      this.noOverlap(this.hitbox, this.lastWall, this.lastDirection);
    }

    if (this.player && this.isHoldingHands) {
      
      let localPointer = this.toLocal(game.input.activePointer.position);
      const lastPos = this.lastPos = new Phaser.Point(this.ninjaGrp.position.x, this.ninjaGrp.position.y);

      this.ninjaGrp.position.x = localPointer.x/*  + this.offset.x */;
      this.ninjaGrp.position.y = localPointer.y/*  + this.offset.y */;

      if (this.ninjaGrp.position.x > 11000) this.game.myEvents.onBeginOutro.dispatch();
      this.game.physics.arcade.overlap(this.hitbox, this.wallsGrp,
        (player, wall) => {
          if (!this.overlapping) {
            this.overlapping = true;
            this.lastWall = wall;

            this.lastDirection = { x: this.ninjaGrp.x - this.lastPos.x, y: this.ninjaGrp.y - this.lastPos.y }
            wall.onCollision(player);
            this.ninjaGrp.position.copyFrom(lastPos);
          }
        }
      );
    }
  }

  noOverlap(player, wall, direction) {

    let lastDirection = { x: 0, y: 0 }
    const xDiff = player.body.center.x - wall.body.center.x;;
    const yDiff = player.body.center.y - wall.body.center.y;

    if (xDiff >= 0) lastDirection.x = -1;
    if (xDiff < 0) lastDirection.x = 1;
    if (yDiff >= 0) lastDirection.y = -1;
    if (yDiff < 0) lastDirection.y = 1;


    if (this.hitbox.overlap(wall)) {
      this.ninjaGrp.x -= lastDirection.x * 5;
      this.ninjaGrp.y -= lastDirection.y * 5;
    } else {
      this.lastWall = false;
      this.checkAllOverlaps();
    }
  }

  checkAllOverlaps() {
    this.game.physics.arcade.overlap(this.hitbox, this.wallsGrp, (player, wall) => {
      this.lastWall = wall;
      this.noOverlap(player, wall, this.lastDirection);
    });
  }

  inputDown() {
    this.isHoldingHands = true;
    this.advance = -1;
    this.ninya.animations.play('run');
    this.parent.timeTouch = this.game.time.totalElapsedSeconds();

    const localPointer = this.toLocal(game.input.activePointer.position);
    const lastPos = new Phaser.Point(this.ninjaGrp.position.x, this.ninjaGrp.position.y);
    this.offset = { x: lastPos.x - localPointer.x, y: lastPos.y - localPointer.y };
    this.game.myEvents.onGirlPick.dispatch(this.finger);
  }

  inputUp() {
    this.isHoldingHands = false;
    this.advance = 1;
    this.ninya.animations.stop('run');
    this.ninya.frameName = 'ninyaTrizte.png';
    this.parent.timeTouch = this.game.time.totalElapsedSeconds();
    this.game.myEvents.onGirlDrop.dispatch(this.finger);
  }

  // Utils

  // Return pos with anchor on 0, 0
  gridToCoord(gridPos) {
    return { x: gridPos.y * TILE_SIZE, y: gridPos.x * TILE_SIZE };
  }

}