import { MapContainer, Marker, Rectangle, TileLayer, Tooltip } from "react-leaflet";
import L from "leaflet";
import { useCallback, useState } from "react";
import Modal from 'react-modal';
import "./index.css";
type SetState<T> = React.Dispatch<React.SetStateAction<T>>;
type StateInit<T> = [T, SetState<T>];

function Login(params: { modal: StateInit<boolean>, login: StateInit<string | undefined>; }) {
    const {modal, login} = params;
    const customStyles = {
        content: {
            top: '50%',
            left: '50%',
            right: 'auto',
            bottom: 'auto',
            marginRight: '-50%',
            transform: 'translate(-50%, -50%)',
        },
    };
    
    const openModal = () => modal[1](true)
    const afterOpenModal = () => { }
    const closeModal = () => modal[1](false)
    return (<>
        <button type="button" onClick={openModal}>Log In</button>
        <Modal
            isOpen={modal[0]}
            onAfterOpen={afterOpenModal}
            onRequestClose={closeModal}
            style={customStyles}
            contentLabel="Log In"
            ariaHideApp={false}
        >
            <h2>Authentification</h2>
            <form action={(e : FormData) => {
                // TODO Check Auth
                const l = e.get("login")
                if (l == null) return;
                closeModal()
                login[1](l.toString())
            }}>
                <input name="login" type="text" placeholder="Login" required={true} /><br />
                <input name="password" type="password" placeholder="Password" required={true} /><br />
                <button id="auth!submit" type="submit">Log In</button>
            </form>
        </Modal>
    </>)
}

function Toolbar(params: { logged_in: [boolean,] }) {

}

export function App() {
    const [modalIsOpen, setModalIsOpen]: StateInit<boolean> = useState(false);
    const [coords, setCoords]: StateInit<{ x: number; y: number }> = useState({ x: 0, y: 0 })
    const [nextLabel, setNextLabel]: StateInit<string> = useState("")
    const [currentZoom, setCurrentZoom]: StateInit<number> = useState(0)
    const [markers, setMarkers]: StateInit<{ label: string; x: number; y: number }[]> = useState([
        { label: "Spawn", x: 0, y: 0 }
    ])
    const [login, setLogin]: StateInit<string | undefined> = useState()

    let map = useCallback((it: L.Map | null) => {
        if (it == null) return;
        it.on('mousemove', (e) => { setCoords({ x: Math.round(e.latlng.lng), y: Math.round(e.latlng.lat) }) })
        it.on('zoomend', (_) => setCurrentZoom(it.getZoom()))
        it.on('click', (e) => setMarkers([...markers, { label: nextLabel, x: Math.round(e.latlng.lng), y: Math.round(e.latlng.lat) }]))
    }, [coords, markers, nextLabel])

    return (<>{ (!modalIsOpen) ?
        <MapContainer
            className={(login) ? "edit" : "fullscreen"}
            id="map"
            center={[0, 0]}
            maxBounds={[[-8192, -8192], [8192, 8192]]}
            crs={L.CRS.Simple}
            zoom={0}
            ref={map}>
            <TileLayer
                url="/static/tiles/{z}/{x}_{y}.png"
                tileSize={512}
                minZoom={-4}
                maxNativeZoom={0} />

            {(currentZoom > -2) ? markers.map((it, i) => (
                <Marker key={i} position={[it.y, it.x]} icon={new L.Icon({ iconUrl: "/static/legend/city.svg", iconAnchor: [6, 6] })}>
                    <Tooltip>{it.label}</Tooltip>
                </Marker>
            )) : null
            }
            <Rectangle bounds={[[-8000, 8000], [8000, 8000]]} pathOptions={{ color: "#000", stroke: true, fill: false, weight: 1 }} />
        </MapContainer> : <></> } {
            (login) ?
                <>
                    <p>Mouse is at {coords.x}, {-coords.y}</p>
                    <label htmlFor="nextmarker">Next Marker Label</label>
                    <input id="nextmarker" type="text" onChange={(e) => setNextLabel(e.target.value)} value={nextLabel} />
                    <p>Hello {login}!</p>
                    <button type="button" onClick={() => setLogin(undefined)}>Log out</button>
                </>
                : <Login login={[login,setLogin]} modal={[modalIsOpen, setModalIsOpen]} />}

    </>)
}

export default App;
