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

const PATH_REGEX =
  /^\/(?:$|(?:[A-Za-z0-9._~-]+|:[A-Za-z0-9_]+)(?:\/(?:[A-Za-z0-9._~-]+|:[A-Za-z0-9_]+))*)$/;

function normalizePath(value: string): string {
  if (!value.startsWith("/")) {
    return `/${value}`;
  }

  if (value.length > 1 && value.endsWith("/")) {
    return value.slice(0, -1);
  }

  return value;
}

export function CreateFunctionPage() {
  const navigate = useNavigate();
  const location = useLocation();
  const { projectId } = useParams<{ projectId: string }>();
  const { isAuthenticated, loading: authLoading } = useAuth();

  const [name, setName] = useState("");
  const [path, setPath] = useState("/");
  const [submitting, setSubmitting] = useState(false);
  const [error, setError] = useState<string | null>(null);

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

  if (!projectId) {
    return (
      <Box sx={{ p: 3 }}>
        <Alert color="danger" variant="soft">
          Missing project identifier. Please return to the dashboard and try
          again.
        </Alert>
      </Box>
    );
  }

  const normalizedPath = normalizePath(path.trim() || "/");
  const pathIsValid = PATH_REGEX.test(normalizedPath);
  const canSubmit = Boolean(name.trim()) && pathIsValid && !submitting;

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

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

    setSubmitting(true);
    setError(null);

    const payload: CreateFunctionDto = {
      name: name.trim(),
      path: normalizedPath,
    };

    try {
      await apiClient.post(`/projects/${projectId}/functions`, payload);
      navigate(`/projects/${projectId}`, { replace: true });
    } catch (err) {
      if (err instanceof AxiosError) {
        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 function");
        } else {
          setError(err.message || "Failed to create function");
        }
      } else if (err instanceof Error) {
        setError(err.message);
      } else {
        setError("Failed to create function");
      }
    } finally {
      setSubmitting(false);
    }
  };

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

        <Box>
          <Typography level="h2" fontWeight={700}>
            New function
          </Typography>
          <Typography level="body-sm" textColor="neutral.500">
            Deploy a new handler for this project.
          </Typography>
        </Box>

        <Card sx={{ p: 3 }}>
          <Stack component="form" gap={2.5} onSubmit={handleSubmit}>
            <FormControl required>
              <FormLabel>Name</FormLabel>
              <Input
                placeholder="Webhook handler"
                value={name}
                onChange={(event) => setName(event.target.value)}
              />
              <FormHelperText>
                Used in the dashboard and logs to identify this function.
              </FormHelperText>
            </FormControl>

            <FormControl required error={!pathIsValid}>
              <FormLabel>Path</FormLabel>
              <Input
                placeholder="/webhooks/payments/:id"
                value={path}
                onChange={(event) => setPath(event.target.value)}
              />
              <FormHelperText>
                Must start with /. Use :param for dynamic segments.
              </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={<Code2 size={18} />}
                loading={submitting}
                disabled={!canSubmit}
              >
                Create function
              </Button>
            </Stack>
          </Stack>
        </Card>
      </Box>
    </Box>
  );
}
