import { useState } from "react";
import {
  Alert,
  Box,
  Button,
  Card,
  FormControl,
  FormHelperText,
  FormLabel,
  Input,
  Stack,
  Textarea,
  Typography,
} from "@mui/joy";
import { AxiosError } from "axios";
import { ArrowLeft, Rocket } from "lucide-react";
import { Navigate, useLocation, useNavigate } from "react-router";
import type { CreateProjectDto } from "@sigma/common";
import { useAuth } from "../../context/auth-context";
import { apiClient } from "../../lib/api";

const SLUG_REGEX = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
const DEFAULT_CPU_QUOTA = 1000;

function slugify(value: string) {
  return value
    .toLowerCase()
    .trim()
    .replace(/[^a-z0-9]+/g, "-")
    .replace(/^-+|-+$/g, "")
    .slice(0, 60);
}

export function CreateProjectPage() {
  const navigate = useNavigate();
  const location = useLocation();
  const { isAuthenticated, loading: authLoading } = useAuth();

  const [name, setName] = useState("");
  const [slug, setSlug] = useState("");
  const [description, setDescription] = useState("");
  const [cpuQuota, setCpuQuota] = useState<string>("");
  const [slugEdited, setSlugEdited] = useState(false);
  const [submitting, setSubmitting] = useState(false);
  const [error, setError] = useState<string | null>(null);

  if (!authLoading && !isAuthenticated) {
    return (
      <Navigate
        to="/login"
        replace
        state={{ from: location.pathname ?? "/projects/new" }}
      />
    );
  }

  const slugIsValid = !slug || SLUG_REGEX.test(slug);
  const quotaNumber = cpuQuota ? Number(cpuQuota) : undefined;
  const quotaIsValid =
    quotaNumber === undefined ||
    (Number.isFinite(quotaNumber) && quotaNumber >= 1);

  const canSubmit =
    Boolean(name.trim()) &&
    Boolean(slug.trim()) &&
    Boolean(description.trim()) &&
    slugIsValid &&
    quotaIsValid &&
    !submitting;

  const handleNameChange = (value: string) => {
    setName(value);
    if (!slugEdited) {
      setSlug(slugify(value));
    }
  };

  const handleSlugChange = (value: string) => {
    setSlugEdited(true);
    setSlug(slugify(value));
  };

  const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
    event.preventDefault();
    if (!canSubmit) {
      return;
    }

    setSubmitting(true);
    setError(null);

    const payload: CreateProjectDto = {
      name: name.trim(),
      slug: slug.trim(),
      description: description.trim(),
    };

    if (quotaNumber !== undefined) {
      payload.cpuTimeQuotaMsPerMinute = quotaNumber;
    }

    try {
      await apiClient.post("/projects", payload);
      navigate("/", { replace: true });
    } catch (err) {
      if (err instanceof AxiosError) {
        if (err.response?.status === 409) {
          setError("A project with this slug already exists.");
        } else if (err.response?.data?.message) {
          const message = Array.isArray(err.response.data.message)
            ? err.response.data.message.join("; ")
            : err.response.data.message;
          setError(message ?? "Failed to create project");
        } else {
          setError(err.message || "Failed to create project");
        }
      } else if (err instanceof Error) {
        setError(err.message);
      } else {
        setError("Failed to create project");
      }
    } finally {
      setSubmitting(false);
    }
  };

  const handleBack = () => {
    if (window.history.length > 2) {
      navigate(-1);
    } else {
      navigate("/");
    }
  };

  return (
    <Box sx={{ p: 3, display: "flex", justifyContent: "center" }}>
      <Box
        sx={{
          width: "100%",
          maxWidth: 800,
          display: "flex",
          flexDirection: "column",
          gap: 2,
        }}
      >
        <Button
          variant="plain"
          color="neutral"
          size="sm"
          startDecorator={<ArrowLeft size={16} />}
          onClick={handleBack}
          sx={{ alignSelf: "flex-start" }}
        >
          Back
        </Button>

        <Box>
          <Typography level="h2" fontWeight={700}>
            New project
          </Typography>
          <Typography level="body-sm" textColor="neutral.500">
            Define the essentials for a new compute project. You can add
            functions right after this step.
          </Typography>
        </Box>

        <Card sx={{ p: 3 }}>
          <Stack component="form" gap={2.5} onSubmit={handleSubmit}>
            <Stack direction={{ xs: "column", sm: "row" }} gap={2}>
              <FormControl required sx={{ flex: 1 }}>
                <FormLabel>Project name</FormLabel>
                <Input
                  placeholder="Payments service"
                  value={name}
                  onChange={(event) => handleNameChange(event.target.value)}
                />
                <FormHelperText>Shown across the dashboard.</FormHelperText>
              </FormControl>
              <FormControl
                required
                sx={{ flex: 1 }}
                error={Boolean(slug) && !slugIsValid}
              >
                <FormLabel>Slug</FormLabel>
                <Input
                  placeholder="payments-service"
                  value={slug}
                  onChange={(event) => handleSlugChange(event.target.value)}
                />
                <FormHelperText>
                  Lowercase letters, numbers, and dashes only ({"/projects/"}
                  {slug || "slug"}).
                </FormHelperText>
              </FormControl>
            </Stack>

            <FormControl required>
              <FormLabel>Description</FormLabel>
              <Textarea
                minRows={3}
                placeholder="Briefly describe what this project powers"
                value={description}
                onChange={(event) => setDescription(event.target.value)}
              />
              <FormHelperText>
                Helps teammates understand the workload.
              </FormHelperText>
            </FormControl>

            {error ? (
              <Alert color="danger" variant="soft">
                {error}
              </Alert>
            ) : null}

            <Stack direction="row" gap={1.5} justifyContent="flex-end">
              <Button
                type="button"
                variant="outlined"
                color="neutral"
                onClick={handleBack}
                disabled={submitting}
              >
                Cancel
              </Button>
              <Button
                type="submit"
                startDecorator={<Rocket size={18} />}
                loading={submitting}
                disabled={!canSubmit}
              >
                Create project
              </Button>
            </Stack>
          </Stack>
        </Card>
      </Box>
    </Box>
  );
}
