import { Box, Button, Heading, Input, Stack, Image, Text } from "@chakra-ui/react";
import { Policy } from "@lib/Policies";
import { Resource } from "@lib/vix/AppResources";
import { SyntheticEvent, useState } from "react";
import { toast } from "react-toastify";
import { useAuth } from "@src/ctx/AuthContext";
import { Links, rootLink, useAutoRedirect } from "@src/util/links";
import { ClientError } from "@dunemask/vix/bridge";
import { AuthErrors } from "@lib/vix/ClientErrors";
import { PasswordInput } from "@src/components/common/Inputs";
import { ResourcePolicyType } from "@dunemask/vix/util";
import { postProjectAuthLogin } from "@src/util/api/GeneratedRequests";
import { Navigate, useSearchParams } from "react-router-dom";
import { useProjectContext } from "@src/ctx/ProjectContext";

export default function AuthenticateView() {
  const { auth, login } = useAuth();
  const { projectId } = useProjectContext();
  const autoRedirect = useAutoRedirect();
  const [search] = useSearchParams();
  const [identity, setIdentity] = useState<string>("");
  const [password, setPassword] = useState<string>("");

  const identityChange = (e: SyntheticEvent) => setIdentity((e.target as HTMLInputElement).value);

  function submitCredentials() {
    const loginPromise = postProjectAuthLogin(projectId, { identity: identity, password }).then(async (creds) => {
      if (!creds.token) return toast.error("Server didn't provide token!");
      await login(
        creds.user,
        creds.token,
        Policy.parseResourcePolicies<Resource>(creds.policies as ResourcePolicyType<Resource>[]),
      );
      autoRedirect();
    });
    toast.promise(loginPromise, {
      pending: "Logging in",
      success: "Logged in successfully!",
      error: {
        render({ data }) {
          const clientError = data as ClientError;
          if (clientError.isError(AuthErrors.UnauthorizedRequest)) return "Incorrect credentials!";
          console.error(data);
          return "Error logging in!";
        },
      },
    });
    setPassword("");
  }

  function detectEnter(e: KeyboardEvent) {
    if (e.key === "Enter") submitCredentials();
  }

  if (auth) return <Navigate to={rootLink(Links.AutoRedirect)} />;
  return (
    <Box width="100%" height="90vh" display="flex" alignItems="center" justifyContent="center">
      <Box p="2rem" width="100%" maxWidth="350px" boxShadow="md" borderRadius="md" bg="background.paper">
        <Stack spacing="4" align="center" w="100%">
          <Stack spacing="2" textAlign="center" w="100%">
            <Heading size="md" display="flex" alignItems="center">
              Sign in
              <Image src={`${import.meta.env.BASE_URL}icons/android-chrome-512x512.png`} boxSize="24px" ml="1rem" alt="Logo" />
            </Heading>
            <Text fontSize="sm" w="100%" textAlign="left">
              Please enter your credentials below
            </Text>
          </Stack>
          <Stack spacing="4" w="100%">
            <Input
              value={identity}
              placeholder="Identity"
              onChange={identityChange}
              isRequired
              autoFocus
              width="100%"
              borderColor="primary"
            />
            <PasswordInput value={password} setPassword={setPassword} isRequired />
          </Stack>
          <Stack direction="row" spacing="4" mt="4" justifyContent="space-between" w="100%">
            <Button
              onClick={submitCredentials}
              variant="outline"
              colorScheme="primary"
              ml="auto"
              isDisabled={!identity || !password}
            >
              Sign in
            </Button>
          </Stack>
        </Stack>
      </Box>
    </Box>
  );
}
