import {MazeCell} from "./model/maze.ts";
import Coordinates from "./model/coordinates.ts";
import {Action, actionClickedCell} from "./state/action.ts";
import styles from "./cell.module.scss";
import "./cell.scss";
import {State} from "./state/state.ts";
import {ActionDispatch} from "react";

function getMarkedDirections(coords: Coordinates, marked: Coordinates[]): Direction[] {
    const cellIndex: number = marked.findIndex(e => e.x === coords.x && e.y === coords.y);
    if (cellIndex === -1) {
        return [];
    }
    if (marked.length === 1) {
        return [Direction.SELF];
    }
    if (cellIndex === 0) {
        const next: Coordinates = marked[1];
        return [Direction.SELF, getDirectionTo(coords, next)];
    } else {
        const previous = marked[cellIndex - 1];
        if (cellIndex === marked.length - 1) {
            return [Direction.SELF, getDirectionTo(coords, previous)];
        }
        const next: Coordinates = marked[cellIndex + 1];
        return [Direction.SELF, getDirectionTo(coords, previous), getDirectionTo(coords, next)];
    }
}

function getDirectionTo(me: Coordinates, other: Coordinates): Direction {
    const xDiff = me.x - other.x;
    switch (xDiff) {
        case -1:
            return Direction.RIGHT;
        case 1:
            return Direction.LEFT;
        default:
            const yDiff = me.y - other.y;
            if (yDiff === -1) {
                return Direction.DOWN;
            }
            return Direction.UP;
    }
}

export default function Cell({x, y, state, dispatch}:
                             {
                                 x: number,
                                 y: number,
                                 state: State,
                                 dispatch: ActionDispatch<[Action]>
                             }) {
    const cell: MazeCell = state.maze!.grid[y][x];
    let classes = " r" + y + " c" + x;
    if (cell.top) classes += " top";
    if (cell.right) classes += " right";
    if (cell.bottom) classes += " bottom";
    if (cell.left) classes += " left";
    if (cell.solution && state.showSolution) classes += " solution";
    const markedDirections = getMarkedDirections({x, y}, state.userPath);
    for (let i = 0; i < markedDirections.length; i++) {
        classes += ` user${Direction[markedDirections[i]]}`;
    }
    return (
        <div className={styles.cell + classes}
             onMouseEnter={(e) => {
                 const leftPressed = e.buttons & 0x1;
                 if (leftPressed) {
                     dispatch(actionClickedCell(x, y));
                 }
             }}
             onClick={() => {
                 dispatch(actionClickedCell(x, y));
             }}>
            <div className={"marker UP"}></div>
            <div className={"marker RIGHT"}></div>
            <div className={"marker DOWN"}></div>
            <div className={"marker LEFT"}></div>
        </div>
    );
}

enum Direction {
    UP, RIGHT, DOWN, LEFT, SELF
}
