import React, { useState, KeyboardEvent, useRef, useContext } from "react";
import {
  Input,
  Button,
  Box,
  Typography,
  Tooltip,
  Dialog,
  DialogTitle,
  DialogContent,
  DialogActions,
} from "@mui/material";
import { GlobalContext, Session } from "./GlobalContext";

interface NameSetterProps {
  onNameSet?: () => void;
  initialName?: string;
  initialPassword?: string;
}

const NameSetter: React.FC<NameSetterProps> = ({ onNameSet, initialName = "", initialPassword = "" }) => {
  const { session, sendJsonMessage } = useContext(GlobalContext);
  const [editName, setEditName] = useState<string>(initialName);
  const [editPassword, setEditPassword] = useState<string>(initialPassword);
  const [showDialog, setShowDialog] = useState<boolean>(!session.name);
  const [isSubmitting, setIsSubmitting] = useState<boolean>(false);

  const nameInputRef = useRef<HTMLInputElement>(null);
  const passwordInputRef = useRef<HTMLInputElement>(null);

  const setName = (name: string) => {
    setIsSubmitting(true);
    sendJsonMessage({
      type: "player-name",
      data: { name, password: editPassword ? editPassword : undefined },
    });
    if (onNameSet) {
      onNameSet();
    }
    setShowDialog(false);
    setIsSubmitting(false);
    setEditName("");
    setEditPassword("");
  };

  const handleNameKeyDown = (event: KeyboardEvent<HTMLInputElement>): void => {
    if (event.key === "Enter") {
      event.preventDefault();
      if (passwordInputRef.current) {
        passwordInputRef.current.focus();
      }
    }
  };

  const handlePasswordKeyDown = (event: KeyboardEvent<HTMLInputElement>): void => {
    if (event.key === "Enter") {
      event.preventDefault();
      handleSubmit();
    }
  };

  const handleSubmit = () => {
    const newName = editName.trim();
    if (!newName || (session?.name && session.name === newName)) {
      return;
    }
    setName(newName);
  };

  const handleOpenDialog = () => {
    setEditName(session.name || "");
    setEditPassword("");
    setShowDialog(true);
    // Focus the name input when dialog opens
    setTimeout(() => {
      if (nameInputRef.current) {
        nameInputRef.current.focus();
      }
    }, 100);
  };

  const handleCloseDialog = () => {
    setShowDialog(false);
    setEditName("");
    setEditPassword("");
  };

  const hasNameChanged = editName.trim() !== (session.name || "");
  const canSubmit = editName.trim() && hasNameChanged && !isSubmitting;

  return (
    <Box sx={{ gap: 1, display: "flex", flexDirection: "column", alignItems: "flex-start" }}>
      {session.name && !showDialog && (
        <Box sx={{ display: "flex", alignItems: "center", gap: 1 }}>
          <Typography>You are logged in as: {session.name}</Typography>
          <Button variant="outlined" size="small" onClick={handleOpenDialog}>
            Change Name
          </Button>
        </Box>
      )}

      {/* Dialog for name change */}
      <Dialog open={showDialog} onClose={handleCloseDialog} maxWidth="sm" fullWidth>
        <DialogTitle>{session.name ? "Change Your Name" : "Enter Your Name"}</DialogTitle>
        <DialogContent>
          <Box sx={{ display: "flex", flexDirection: "column", gap: 2, pt: 1 }}>
            <Typography variant="body2" color="text.secondary">
              {session.name ? "Enter a new name to change your current name." : "Enter your name to join the lobby."}
            </Typography>
            <Typography variant="caption" color="text.secondary">
              You can optionally set a password to reserve this name; supply it again to takeover the name from another
              client.
            </Typography>

            <Input
              inputRef={nameInputRef}
              type="text"
              value={editName}
              onChange={(e): void => {
                setEditName(e.target.value);
              }}
              onKeyDown={handleNameKeyDown}
              placeholder="Your name"
              fullWidth
              autoFocus
            />

            <Input
              inputRef={passwordInputRef}
              type="password"
              value={editPassword}
              onChange={(e): void => setEditPassword(e.target.value)}
              onKeyDown={handlePasswordKeyDown}
              placeholder="Optional password"
              fullWidth
            />

            <Tooltip title="Optional: choose a short password to reserve this name. Keep it secret.">
              <span />
            </Tooltip>
          </Box>
        </DialogContent>
        <DialogActions>
          <Button onClick={handleCloseDialog} disabled={isSubmitting}>
            Cancel
          </Button>
          <Button
            variant="contained"
            onClick={handleSubmit}
            disabled={!canSubmit}
            color={hasNameChanged ? "primary" : "inherit"}
          >
            {isSubmitting ? "Changing..." : session.name ? "Change Name" : "Join"}
          </Button>
        </DialogActions>
      </Dialog>
    </Box>
  );
};

export default NameSetter;
