import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { useEffect, useMemo, useState } from "react";
import { toast } from "sonner";
import { Button } from "../../components/ui/button";
import { Dialog, DialogContent, DialogFooter, } from "../../components/ui/dialog";
import { StyledDialogTitle } from "../../components/ui/styled-dialog-title";
import { Input } from "../../components/ui/input";
import { Label } from "../../components/ui/label";
import { Textarea } from "../../components/ui/textarea";
import { FolderPlus } from "lucide-react";
import { createProject, getProjectTemplates } from "../services/taskService";
import { flattenProjectsHierarchy } from "../utils/projectHierarchy";
import { Select } from "../../components/ui/select";
const PREFIX_STOP_WORDS = new Set([
    "A",
    "AN",
    "AND",
    "AS",
    "AT",
    "BY",
    "FOR",
    "FROM",
    "IN",
    "OF",
    "ON",
    "OR",
    "THE",
    "TO",
    "WITH",
]);
function formatCostLimit(value) {
    const asString = String(value).trim();
    return asString.length > 0 ? asString : "25";
}
function sanitizePrefix(value) {
    return value
        .toUpperCase()
        .replace(/[^A-Z0-9]/g, "")
        .slice(0, 4);
}
function suggestPrefixFromTitle(title) {
    const words = title
        .toUpperCase()
        .split(/[^A-Z0-9]+/)
        .filter(Boolean);
    if (words.length === 0)
        return "";
    const meaningfulWords = words.filter((w) => !PREFIX_STOP_WORDS.has(w));
    const sourceWords = meaningfulWords.length > 0 ? meaningfulWords : words;
    let prefix = sourceWords
        .slice(0, 4)
        .map((w) => w[0])
        .join("");
    if (prefix.length < 4) {
        const primary = sourceWords[0] || "";
        const consonants = primary
            .slice(1)
            .replace(/[AEIOU]/g, "")
            .split("")
            .filter((ch) => /[A-Z0-9]/.test(ch));
        prefix += consonants.join("");
    }
    if (prefix.length < 4) {
        prefix += sourceWords.join("");
    }
    const finalPrefix = sanitizePrefix(prefix);
    return finalPrefix || "PRJ";
}
export function CreateProjectDialog(props) {
    const DEFAULT_COST_LIMIT = "25";
    const { open, onOpenChange, projects = [], onCreated } = props;
    const [title, setTitle] = useState("");
    const [description, setDescription] = useState("");
    const [taskPrefix, setTaskPrefix] = useState("");
    const [taskPrefixEdited, setTaskPrefixEdited] = useState(false);
    const [costLimit, setCostLimit] = useState(DEFAULT_COST_LIMIT);
    const [projectTemplateId, setProjectTemplateId] = useState("");
    const [parentProjectId, setParentProjectId] = useState("");
    const [projectTemplates, setProjectTemplates] = useState([]);
    const [templatesLoading, setTemplatesLoading] = useState(false);
    const [templatesError, setTemplatesError] = useState(null);
    const [submitting, setSubmitting] = useState(false);
    useEffect(() => {
        if (!open)
            return;
        setProjectTemplateId("");
        let cancelled = false;
        setTemplatesLoading(true);
        setTemplatesError(null);
        void getProjectTemplates()
            .then((result) => {
            if (cancelled)
                return;
            if (result.type !== "success") {
                throw new Error(result.summary || "Failed to load project templates");
            }
            const templates = result.data ?? [];
            const selectableTemplates = templates.filter((template) => template.hideFromCreateDialog !== true);
            setProjectTemplates(templates);
            setProjectTemplateId((current) => {
                if (current &&
                    selectableTemplates.some((template) => template.id === current)) {
                    return current;
                }
                return "";
            });
        })
            .catch((e) => {
            if (cancelled)
                return;
            setProjectTemplates([]);
            setProjectTemplateId("");
            setTemplatesError(e?.message || "Failed to load project templates");
        })
            .finally(() => {
            if (!cancelled)
                setTemplatesLoading(false);
        });
        return () => {
            cancelled = true;
        };
    }, [open]);
    const parentProjectOptions = useMemo(() => [
        { value: "", label: "No parent project" },
        ...flattenProjectsHierarchy(projects.map((projectWithPermission) => ({
            projectId: projectWithPermission.project.projectId,
            parentProjectId: projectWithPermission.project.parentProjectId ?? null,
            title: projectWithPermission.project.title,
            permission: projectWithPermission.permission,
        }))).map((project) => ({
            value: project.projectId,
            label: `${"  ".repeat(Math.max(0, project.depth ?? 0))}${project.title} (${project.permission})`,
        })),
    ], [projects]);
    const selectableProjectTemplates = useMemo(() => projectTemplates.filter((template) => template.hideFromCreateDialog !== true), [projectTemplates]);
    const selectedProjectTemplate = useMemo(() => selectableProjectTemplates.find((template) => template.id.toLowerCase() === projectTemplateId.toLowerCase()), [projectTemplateId, selectableProjectTemplates]);
    const projectTemplateOptions = useMemo(() => selectableProjectTemplates.map((template) => {
        const desc = template.description?.trim();
        return {
            value: template.id,
            label: template.name,
            ...(desc ? { description: desc } : {}),
        };
    }), [selectableProjectTemplates]);
    const suggestedPrefix = useMemo(() => {
        return suggestPrefixFromTitle(title.trim());
    }, [title]);
    useEffect(() => {
        if (!projectTemplateId) {
            if (selectableProjectTemplates.length === 0) {
                setCostLimit(DEFAULT_COST_LIMIT);
            }
            return;
        }
        const selectedTemplate = selectableProjectTemplates.find((template) => template.id.toLowerCase() === projectTemplateId.toLowerCase());
        if (!selectedTemplate)
            return;
        setCostLimit(formatCostLimit(selectedTemplate.defaultCostLimit ?? DEFAULT_COST_LIMIT));
    }, [DEFAULT_COST_LIMIT, projectTemplateId, selectableProjectTemplates]);
    useEffect(() => {
        if (!selectedProjectTemplate) {
            setDescription("");
            return;
        }
        const text = selectedProjectTemplate.description?.trim();
        setDescription(text ?? "");
    }, [selectedProjectTemplate]);
    useEffect(() => {
        if (taskPrefixEdited)
            return;
        setTaskPrefix(suggestedPrefix);
    }, [suggestedPrefix, taskPrefixEdited]);
    const submit = async () => {
        if (!title.trim()) {
            toast.error("Project title is required");
            return;
        }
        const parsedCostLimit = Number(costLimit);
        if (Number.isNaN(parsedCostLimit) || parsedCostLimit <= 0) {
            toast.error("Cost limit must be greater than 0");
            return;
        }
        if (selectableProjectTemplates.length > 0 && !projectTemplateId) {
            toast.error("Project template is required");
            return;
        }
        const body = {
            title: title.trim(),
            parentProjectId: parentProjectId || null,
            description: description.trim() ? description.trim() : undefined,
            taskPrefix: taskPrefix.trim()
                ? sanitizePrefix(taskPrefix.trim())
                : undefined,
            costLimit: parsedCostLimit,
            projectTemplateId: projectTemplateId || undefined,
        };
        setSubmitting(true);
        try {
            const result = await createProject(body);
            if (result.type !== "success") {
                toast.error(result.summary || "Failed to create project");
                return;
            }
            const projectId = result.data?.project?.projectId ?? null;
            toast.success("Project created");
            onOpenChange(false);
            await onCreated({
                projectId,
                openInWizardMode: selectedProjectTemplate?.openInWizardMode === true,
            });
            // reset
            setTitle("");
            setDescription("");
            setTaskPrefix("");
            setTaskPrefixEdited(false);
            setCostLimit(DEFAULT_COST_LIMIT);
            setProjectTemplateId("");
            setParentProjectId("");
        }
        finally {
            setSubmitting(false);
        }
    };
    return (_jsx(Dialog, { open: open, onOpenChange: onOpenChange, children: _jsxs(DialogContent, { className: "max-w-lg", "data-testid": "taskboard-create-project-dialog", children: [_jsx(StyledDialogTitle, { icon: _jsx(FolderPlus, { strokeWidth: 1 }), title: "Create Project", subtitle: "Create a project from task templates" }), _jsxs("div", { className: "grid min-h-0 flex-1 gap-6 overflow-y-auto p-6", children: [(templatesLoading ||
                            templatesError ||
                            selectableProjectTemplates.length > 0) && (_jsxs("div", { className: "grid gap-2", children: [_jsx(Label, { htmlFor: "projectTemplate", children: "Project template" }), _jsx(Select, { id: "projectTemplate", "data-testid": "taskboard-project-template-select", value: projectTemplateId, onValueChange: setProjectTemplateId, options: projectTemplateOptions, placeholder: templatesLoading
                                        ? "Loading templates..."
                                        : "Select a project template", loading: templatesLoading, emptyMessage: "No project templates available.", searchable: projectTemplateOptions.length > 6 }), selectedProjectTemplate?.defaultCostLimit != null && (_jsxs("div", { className: "text-muted-foreground text-xs", children: ["Applies default cost limit of", " ", selectedProjectTemplate.defaultCostLimit, "."] })), templatesError && (_jsx("div", { className: "text-feedback-red text-xs", children: templatesError }))] })), _jsxs("div", { className: "grid gap-2", children: [_jsx(Label, { htmlFor: "projectTitle", children: "Title" }), _jsx(Input, { id: "projectTitle", "data-testid": "taskboard-project-title-input", value: title, onChange: (e) => setTitle(e.target.value), placeholder: "e.g. Spring Launch" })] }), _jsxs("div", { className: "grid gap-2", children: [_jsx(Label, { htmlFor: "projectDescription", children: "Project description" }), _jsx(Textarea, { id: "projectDescription", "data-testid": "taskboard-project-description-input", className: "text-xs", value: description, onChange: (e) => setDescription(e.target.value), placeholder: "Optional description", rows: 3 })] }), _jsxs("div", { className: "grid gap-2", children: [_jsx(Label, { htmlFor: "projectParent", children: "Parent project" }), _jsx(Select, { id: "projectParent", "data-testid": "taskboard-project-parent-select", value: parentProjectId, onValueChange: setParentProjectId, options: parentProjectOptions, placeholder: "No parent project" }), _jsx("div", { className: "text-muted-foreground text-xs", children: "Choose a parent to create this as a subproject." })] }), _jsxs("div", { className: "grid gap-2", children: [_jsx(Label, { htmlFor: "projectTaskPrefix", children: "Task prefix" }), _jsx(Input, { id: "projectTaskPrefix", "data-testid": "taskboard-project-prefix-input", value: taskPrefix, onChange: (e) => {
                                        setTaskPrefixEdited(true);
                                        setTaskPrefix(sanitizePrefix(e.target.value));
                                    }, placeholder: "e.g. WEB", maxLength: 4 }), _jsx("div", { className: "text-muted-foreground text-xs", children: "Suggested from title. Max 4 chars, used for task IDs like WEB1-1." })] }), _jsxs("div", { className: "grid gap-2", children: [_jsx(Label, { htmlFor: "projectCostLimit", children: "Cost limit" }), _jsx(Input, { id: "projectCostLimit", "data-testid": "taskboard-project-cost-limit-input", value: costLimit, onChange: (e) => setCostLimit(e.target.value), placeholder: DEFAULT_COST_LIMIT })] })] }), _jsxs(DialogFooter, { className: "flex flex-row items-center justify-end gap-2 p-4", children: [_jsx(Button, { variant: "outline", onClick: () => onOpenChange(false), disabled: submitting, "data-testid": "taskboard-project-cancel-button", children: "Cancel" }), _jsx(Button, { onClick: submit, disabled: submitting || !title.trim(), "data-testid": "taskboard-project-submit-button", children: submitting ? "Creating..." : "Create Project" })] })] }) }));
}
//# sourceMappingURL=CreateProjectDialog.js.map