package states;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

import gos.AutomatedUnitManager;
import gos.Entity;
import gos.ItemManager;
import gos.ManualUnitManager;
import main.AppPanel;
import ui.GameOverPanel;
import ui.OnClickListener;
import ui.ShowTextOnHoverButton;
import ui.TextPanel;
import ui.UIElementManager;
import ui.UnitPanel;

public class PlayState implements AppState {

	public static boolean isAIsTurn = false;

	private ShowTextOnHoverButton nextTurn;
	private UIElementManager uiem;

	private ManualUnitManager mum;
	private AutomatedUnitManager aum;
	private ItemManager im;

	private int turnCount = 1;

	List<Entity> drawHudFors = new CopyOnWriteArrayList<>();

	private GameOverPanel gop = new GameOverPanel();
	
	public PlayState() {
		int x = AppPanel.WIDTH - 200;
		int y = AppPanel.HEIGHT - 75;
		int w = 150;
		int h = 50;
		nextTurn = new ShowTextOnHoverButton(x, y, w, h);
		nextTurn.setTextPanel(new TextPanel(x, y - h - 5, w, h).setText("Each cell may move and attack once every turn :)").setBg_color(new Color(50, 200, 255, 230))).setBg_color(new Color(50, 150, 255, 230)).setText("End Your Turn");

		nextTurn.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick() {
				if (isAIsTurn)
					return;
				clickedNextTurn();
			}
		});
		mum = new ManualUnitManager();
		aum = new AutomatedUnitManager();
		im = new ItemManager();

		aum.setMum(mum);
		mum.setAum(aum);

		uiem = new UIElementManager();
		uiem.add(nextTurn, new UnitPanel(mum), gop);

		im.addItem();
	}

	@Override
	public void update() {
		if(mum.getEntities().isEmpty()) {
			gop.show(false, mum.numCellsCapt, aum.cellsCapt, im.whitesItemCount);
			return;
		}
		
		if(aum.getEntities().isEmpty()) {
			gop.show(true, mum.numCellsCapt, aum.cellsCapt, im.whitesItemCount);
			return;
		}
		
		im.checkcollisions(aum.getEntities(), mum.getEntities());
		
		uiem.update();
		mum.update();
		aum.update();

		if (isAIsTurn) {
			nextTurn.setText("Waiting for ai...");
		} else {
			nextTurn.setText("End Your Turn");
		}
	}

	@Override
	public void draw(Graphics2D g2) {
		/// draw bg color
		g2.setColor(new Color(255, 178, 127));
		g2.fillRect(0, 0, AppPanel.WIDTH, AppPanel.HEIGHT);

		// draw play state specific hud 
		g2.setColor(Color.WHITE);
		g2.drawString("Turn: " + turnCount, AppPanel.WIDTH - 70, 20);
		g2.drawString("White Blood Cells: " + mum.getEntities().size(), 20, 20);
		g2.drawString("Black Cancer Cells: " + aum.getEntities().size(), 20, 40);
		int cancerSplit =(4 - (turnCount % 4));
		g2.drawString("Cancer spliting " +  (cancerSplit == 1 ? "next turn." : "in " + cancerSplit + " turns"), 300, 20);
		int itmeSpawn = (2 - (turnCount % 2));
		g2.drawString("New bonus item " + (itmeSpawn == 1 ? "next turn." : "in " + itmeSpawn + " turns"), 300, 40);
		
		im.draw(g2);

		// draw gos
		aum.draw(g2);
		mum.draw(g2);

		// draw hud for gos
		for (Entity e : drawHudFors) {
			g2.setColor(Color.RED);
			g2.fillRect((int) e.getX(), (int) (e.getY() + e.getRadius() * 2) + 1, (int) (e.getRadius() * 2), 7);

			g2.setColor(Color.GREEN);
			g2.fillRect((int) e.getX(), (int) (e.getY() + e.getRadius() * 2) + 1, (int) ((e.getHealth() / e.getType().MAX_HEALTH) * (e.getRadius() * 2)), 7);

		}
		if(isAIsTurn) {
			for (Entity e : mum.getEntities()) {
				g2.setColor(Color.RED);
				g2.fillRect((int) e.getX(), (int) (e.getY() + e.getRadius() * 2) + 1, (int) (e.getRadius() * 2), 7);

				g2.setColor(Color.GREEN);
				g2.fillRect((int) e.getX(), (int) (e.getY() + e.getRadius() * 2) + 1, (int) ((e.getHealth() / e.getType().MAX_HEALTH) * (e.getRadius() * 2)), 7);
			}
		} else {
			for (Entity e : aum.getEntities()) {
				g2.setColor(Color.RED);
				g2.fillRect((int) e.getX(), (int) (e.getY() + e.getRadius() * 2) + 1, (int) (e.getRadius() * 2), 7);

				g2.setColor(Color.GREEN);
				g2.fillRect((int) e.getX(), (int) (e.getY() + e.getRadius() * 2) + 1, (int) ((e.getHealth() / e.getType().MAX_HEALTH) * (e.getRadius() * 2)), 7);
			}
		}

		// draw ui
		uiem.draw(g2);
	}

	@Override
	public void keyPressed(int keycode) {

	}

	@Override
	public void keyReleased(int keycode) {
		if(keycode == KeyEvent.VK_SPACE) {
			mum.deselect();
		}
	}

	@Override
	public void mouseMoved(MouseEvent e) {
		uiem.mouseMoved(e);
		mum.mouseMoved(e);
		addHealthBarToDraw(e);
	}

	@Override
	public void mousePressed(MouseEvent e) {
		uiem.mousePressed(e);
		addHealthBarToDraw(e);
	}

	@Override
	public void mouseReleased(MouseEvent e) {
		uiem.mouseReleased(e);
		mum.mouseReleased(e);
		addHealthBarToDraw(e);
	}

	private void clickedNextTurn() {
		turnCount++;
		if(turnCount % 2 == 0) 
			im.addItem();
		
		if(turnCount % 4 == 0)
			aum.splitCancerCells();

		isAIsTurn = true;
		mum.onNewTurn();
	}

	// draw health bars on hoover
	private void addHealthBarToDraw(MouseEvent e) {
		List<Entity> entities = new CopyOnWriteArrayList<>();
		List<Entity> drawHudFors = new CopyOnWriteArrayList<>();
		entities.addAll(mum.getEntities());
		entities.addAll(aum.getEntities());
		for (Entity acell : entities) {
			float dx = (acell.getX() + acell.getRadius()) - (e.getX());
			float dy = (acell.getY() + acell.getRadius()) - (e.getY());

			double dist = Math.sqrt(dx * dx + dy * dy);
			if (dist < acell.getRadius()) {
				drawHudFors.add(acell);
			}
		}

		this.drawHudFors = drawHudFors;
	}
}
