import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } 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 { Select } from "../../components/ui/select";
import { ProjectExecutionUserPicker } from "./ProjectExecutionUserPicker";
import { Textarea } from "../../components/ui/textarea";
import { DeleteIcon } from "../../components/ui/delete-icon";
import { cn } from "../../lib/utils";
import { ChevronRight, GitBranch, Settings } from "lucide-react";
import { addProjectDependency, addProjectMember, getProjectMembers, getProjectDependencies, removeProjectDependency, removeProjectMember, updateProject, } from "../services/taskService";
const DEFAULT_COST_LIMIT = "25";
export function ProjectSettingsPanel(props) {
    const { projectId, selectedProject, projects, onChanged, active = true, canOpenSourceTemplate = false, onOpenSourceTemplate, onDeleteProject, onSaved, onClose, className, } = props;
    const [members, setMembers] = useState([]);
    const [projectDependencies, setProjectDependencies] = useState([]);
    const [loading, setLoading] = useState(false);
    const [loadingProjectDependencies, setLoadingProjectDependencies] = useState(false);
    const [savingProject, setSavingProject] = useState(false);
    const [savingProjectDependency, setSavingProjectDependency] = useState(false);
    const [removingProjectDependencyId, setRemovingProjectDependencyId] = useState(null);
    const [titleInput, setTitleInput] = useState("");
    const [descriptionInput, setDescriptionInput] = useState("");
    const [costLimitInput, setCostLimitInput] = useState("");
    const [statusInput, setStatusInput] = useState("Active");
    const [executionUserIdInput, setExecutionUserIdInput] = useState("");
    const [executionUserDisplayNameInput, setExecutionUserDisplayNameInput] = useState("");
    const [dependencyProjectId, setDependencyProjectId] = useState("");
    const [memberType, setMemberType] = useState("User");
    const [memberIdentifier, setMemberIdentifier] = useState("");
    const [permission, setPermission] = useState("Viewer");
    const [showProjectDependencies, setShowProjectDependencies] = useState(false);
    const [showMembers, setShowMembers] = useState(false);
    const canManage = selectedProject?.permission === "Owner";
    const sourceTemplateId = selectedProject?.project.sourceProjectTemplateId ?? null;
    const sourceTemplateName = selectedProject?.project.sourceProjectTemplateName ?? null;
    const canDeleteProject = canManage && !!projectId && !!onDeleteProject;
    useEffect(() => {
        if (!active || !selectedProject)
            return;
        const initialExecutionUserId = selectedProject.project.executionUserId ??
            selectedProject.project.createdBy ??
            "";
        const initialExecutionUserDisplayName = selectedProject.project.executionUserDisplayName ??
            initialExecutionUserId;
        setTitleInput(selectedProject.project.title ?? "");
        setDescriptionInput(selectedProject.project.description ?? "");
        setCostLimitInput(selectedProject.project.costLimit == null
            ? DEFAULT_COST_LIMIT
            : String(selectedProject.project.costLimit));
        setStatusInput(selectedProject.project.status ?? "Active");
        setExecutionUserIdInput(initialExecutionUserId);
        setExecutionUserDisplayNameInput(initialExecutionUserDisplayName);
        setDependencyProjectId("");
        setShowProjectDependencies(false);
        setShowMembers(false);
    }, [active, selectedProject]);
    const projectTitlesById = useMemo(() => {
        const map = new Map();
        for (const project of projects) {
            map.set(project.project.projectId, project.project.title);
        }
        return map;
    }, [projects]);
    const siblingProjectOptions = useMemo(() => {
        const parentProjectId = selectedProject?.project.parentProjectId;
        if (!selectedProject || !parentProjectId)
            return [];
        const existingDependencyIds = new Set(projectDependencies.map((dependency) => dependency.dependsOnProjectId));
        return projects
            .filter((project) => project.project.projectId !== selectedProject.project.projectId &&
            project.project.parentProjectId === parentProjectId &&
            !existingDependencyIds.has(project.project.projectId))
            .sort((a, b) => a.project.title.localeCompare(b.project.title))
            .map((project) => ({
            value: project.project.projectId,
            label: project.project.title,
        }));
    }, [projectDependencies, projects, selectedProject]);
    const refreshMembers = async () => {
        if (!projectId)
            return;
        setLoading(true);
        try {
            const result = await getProjectMembers(projectId);
            if (result.type !== "success") {
                toast.error(result.summary || "Failed to load members");
                return;
            }
            setMembers(result.data || []);
        }
        finally {
            setLoading(false);
        }
    };
    const refreshProjectDependencies = async () => {
        if (!projectId)
            return;
        setLoadingProjectDependencies(true);
        try {
            const result = await getProjectDependencies(projectId);
            if (result.type !== "success") {
                toast.error(result.summary || "Failed to load project dependencies");
                return;
            }
            setProjectDependencies(result.data || []);
        }
        finally {
            setLoadingProjectDependencies(false);
        }
    };
    useEffect(() => {
        if (!active)
            return;
        void refreshMembers();
        void refreshProjectDependencies();
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [active, projectId]);
    const submitAdd = async () => {
        if (!projectId)
            return;
        if (!canManage) {
            toast.error("Only owners can manage members");
            return;
        }
        if (!memberIdentifier.trim()) {
            toast.error("Member identifier is required");
            return;
        }
        const result = await addProjectMember({
            projectId,
            memberType,
            memberIdentifier: memberIdentifier.trim(),
            permission,
        });
        if (result.type !== "success") {
            toast.error(result.summary || "Failed to add member");
            return;
        }
        toast.success("Member added");
        setMemberIdentifier("");
        await refreshMembers();
        await onChanged();
    };
    const submitProjectSettings = async () => {
        if (!projectId)
            return;
        if (!canManage) {
            toast.error("Only owners can edit project settings");
            return;
        }
        if (!titleInput.trim()) {
            toast.error("Project title is required");
            return;
        }
        const parsedCostLimit = Number(costLimitInput);
        if (Number.isNaN(parsedCostLimit) || parsedCostLimit <= 0) {
            toast.error("Cost limit must be greater than 0");
            return;
        }
        const normalizedExecutionUserId = executionUserIdInput.trim();
        const normalizedExecutionUserDisplayName = executionUserDisplayNameInput.trim() || normalizedExecutionUserId;
        if (!normalizedExecutionUserId) {
            toast.error("Agent execution user is required");
            return;
        }
        setSavingProject(true);
        try {
            const result = await updateProject({
                projectId,
                title: titleInput.trim(),
                description: descriptionInput.trim() ? descriptionInput.trim() : "",
                costLimit: parsedCostLimit,
                status: statusInput,
                executionUserId: normalizedExecutionUserId,
                executionUserDisplayName: normalizedExecutionUserDisplayName,
            });
            if (result.type !== "success") {
                toast.error(result.summary || "Failed to update project");
                return;
            }
            // toast.success("Project settings updated");
            await onChanged();
            onSaved?.();
        }
        finally {
            setSavingProject(false);
        }
    };
    const submitAddProjectDependency = async () => {
        if (!projectId)
            return;
        if (!canManage) {
            toast.error("Only owners can edit project settings");
            return;
        }
        if (!dependencyProjectId) {
            toast.error("Choose a sibling subproject");
            return;
        }
        setSavingProjectDependency(true);
        try {
            const result = await addProjectDependency({
                projectId,
                dependsOnProjectId: dependencyProjectId,
                dependencyType: "BlockedBy",
            });
            if (result.type !== "success") {
                toast.error(result.summary || "Failed to add project dependency");
                return;
            }
            toast.success("Subproject dependency added");
            setDependencyProjectId("");
            await refreshProjectDependencies();
            await onChanged();
        }
        finally {
            setSavingProjectDependency(false);
        }
    };
    const submitRemoveProjectDependency = async (projectDependencyId) => {
        if (!canManage)
            return;
        setRemovingProjectDependencyId(projectDependencyId);
        try {
            const result = await removeProjectDependency({ projectDependencyId });
            if (result.type !== "success") {
                toast.error(result.summary || "Failed to remove project dependency");
                return;
            }
            toast.success("Subproject dependency removed");
            await refreshProjectDependencies();
            await onChanged();
        }
        finally {
            setRemovingProjectDependencyId(null);
        }
    };
    const submitRemove = async (memberId) => {
        if (!canManage)
            return;
        const result = await removeProjectMember(memberId);
        if (result.type !== "success") {
            toast.error(result.summary || "Failed to remove member");
            return;
        }
        toast.success("Member removed");
        await refreshMembers();
        await onChanged();
    };
    return (_jsxs("div", { className: cn("border-border-default flex min-h-0 w-full max-w-[1000px] flex-col rounded-md border bg-white", className), "data-testid": "taskboard-project-settings-panel", children: [_jsx("div", { className: "min-h-0 flex-1 overflow-y-auto", children: _jsxs("div", { className: "grid gap-4 p-4 sm:gap-6 sm:p-6", children: [_jsxs("div", { className: "grid gap-2", children: [_jsx(Label, { htmlFor: "projectSettingsTitle", className: "text-xs font-medium", children: "Title" }), _jsx(Input, { id: "projectSettingsTitle", value: titleInput, onChange: (e) => setTitleInput(e.target.value), disabled: !canManage || savingProject, placeholder: "Project title" })] }), _jsxs("div", { className: "grid gap-2", children: [_jsx(Label, { htmlFor: "projectSettingsDescription", className: "text-xs font-medium", children: "Description" }), _jsx(Textarea, { id: "projectSettingsDescription", className: "text-xs", value: descriptionInput, onChange: (e) => setDescriptionInput(e.target.value), disabled: !canManage || savingProject, placeholder: "Optional description", rows: 3 })] }), _jsxs("div", { className: "grid gap-2", children: [_jsx(Label, { htmlFor: "projectSettingsCostLimit", className: "text-xs font-medium", children: "Cost limit" }), _jsx(Input, { id: "projectSettingsCostLimit", value: costLimitInput, onChange: (e) => setCostLimitInput(e.target.value), disabled: !canManage || savingProject, placeholder: DEFAULT_COST_LIMIT })] }), _jsxs("div", { className: "grid gap-2", children: [_jsx(Label, { htmlFor: "projectSettingsStatus", className: "text-xs font-medium", children: "Status" }), _jsx(Select, { id: "projectSettingsStatus", value: statusInput, onValueChange: (v) => setStatusInput(v), disabled: !canManage || savingProject, options: [
                                        { value: "Planning", label: "Planning" },
                                        { value: "Active", label: "Active" },
                                        { value: "Finished", label: "Finished" },
                                        { value: "Archived", label: "Archived" },
                                    ] })] }), _jsxs("div", { className: "grid gap-2", children: [_jsx(Label, { htmlFor: "projectSettingsCreatedBy", className: "text-xs font-medium", children: "Created by" }), _jsx(Input, { id: "projectSettingsCreatedBy", value: selectedProject?.project.createdBy ?? "", disabled: true, "data-testid": "taskboard-project-settings-created-by" })] }), sourceTemplateId && sourceTemplateName ? (_jsxs("div", { className: "grid gap-2", children: [_jsx(Label, { className: "text-xs font-medium", children: "Created from template" }), _jsxs("div", { className: "border-border-default bg-neutral-grey-5/50 flex min-h-9 items-center justify-between gap-3 rounded-md border px-3 py-2", children: [_jsxs("div", { className: "text-neutral-grey-100 flex min-w-0 items-center gap-2 text-sm", children: [_jsx(GitBranch, { className: "text-neutral-grey-50 h-4 w-4 shrink-0", strokeWidth: 1, "aria-hidden": true }), _jsx("span", { className: "truncate", children: sourceTemplateName })] }), canOpenSourceTemplate && onOpenSourceTemplate ? (_jsx(Button, { type: "button", variant: "ghost", size: "sm", className: "shrink-0", onClick: () => onOpenSourceTemplate(sourceTemplateId), "data-testid": "taskboard-project-source-template", children: "Open" })) : null] })] })) : null, _jsxs("div", { className: "grid gap-2", children: [_jsx(Label, { className: "text-xs font-medium", children: "Agents run as" }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("div", { className: "min-w-0 flex-1", children: projectId ? (_jsx(ProjectExecutionUserPicker, { projectId: projectId, value: executionUserIdInput, displayValue: executionUserDisplayNameInput, disabled: !canManage || savingProject, buttonTestId: "taskboard-project-settings-execution-user", placeholder: "Choose project execution user", onChange: (next) => {
                                                    setExecutionUserIdInput(next.userId);
                                                    setExecutionUserDisplayNameInput(next.displayName);
                                                } })) : null }), _jsx(Button, { type: "button", variant: "outline", size: "sm", className: "shrink-0", onClick: () => {
                                                const creatorUserName = selectedProject?.project.createdBy ?? "";
                                                setExecutionUserIdInput(creatorUserName);
                                                setExecutionUserDisplayNameInput(creatorUserName);
                                            }, disabled: !canManage ||
                                                savingProject ||
                                                !selectedProject?.project.createdBy, children: "Use creator" })] }), _jsx("div", { className: "text-muted-foreground text-xs", children: "Agents in Workflow Projects impersonate this Sitecore user when they run project work." })] }), _jsx("div", { className: "grid gap-2", children: _jsxs(Button, { type: "button", variant: "ghost", className: "h-auto justify-between px-0 py-0 text-left hover:bg-transparent", onClick: () => setShowProjectDependencies((value) => !value), children: [_jsxs("div", { className: "grid gap-1 text-left", children: [_jsx("div", { className: "text-sm font-medium", children: "Subproject dependencies" }), _jsx("div", { className: "text-muted-foreground text-xs", children: "Execution in this subproject stays blocked until each selected sibling subproject is marked Finished." })] }), _jsx(ChevronRight, { strokeWidth: 1, className: `h-4 w-4 shrink-0 transition-transform ${showProjectDependencies ? "rotate-90" : ""}` })] }) }), showProjectDependencies ? (_jsxs(_Fragment, { children: [_jsx("div", { className: "max-h-48 overflow-auto rounded-md border", children: loadingProjectDependencies ? (_jsx("div", { className: "text-muted-foreground p-3 text-sm", children: "Loading..." })) : projectDependencies.length === 0 ? (_jsx("div", { className: "text-muted-foreground p-3 text-sm", children: "No subproject dependencies." })) : (_jsx("div", { className: "divide-y", children: projectDependencies.map((dependency) => {
                                            const dependencyTitle = projectTitlesById.get(dependency.dependsOnProjectId) ||
                                                dependency.dependsOnProjectId;
                                            return (_jsxs("div", { className: "flex items-center justify-between gap-2 p-3", children: [_jsxs("div", { className: "min-w-0", children: [_jsx("div", { className: "truncate text-sm font-medium", children: dependencyTitle }), _jsx("div", { className: "text-muted-foreground truncate text-xs", children: "Blocks this subproject until status is Finished" })] }), _jsx(Button, { variant: "secondary", onClick: () => submitRemoveProjectDependency(dependency.projectDependencyId), disabled: !canManage ||
                                                            removingProjectDependencyId ===
                                                                dependency.projectDependencyId, children: removingProjectDependencyId ===
                                                            dependency.projectDependencyId
                                                            ? "Removing..."
                                                            : "Remove" })] }, dependency.projectDependencyId));
                                        }) })) }), _jsxs("div", { className: "grid grid-cols-12 items-end gap-2", children: [_jsx("div", { className: "col-span-11", children: _jsxs("div", { className: "grid gap-1.5", children: [_jsx(Label, { className: "text-xs font-medium", children: "Blocked by sibling subproject" }), _jsx(Select, { value: dependencyProjectId, onValueChange: setDependencyProjectId, disabled: !canManage || savingProjectDependency, options: siblingProjectOptions, placeholder: selectedProject?.project.parentProjectId
                                                            ? "Select a sibling subproject"
                                                            : "Only subprojects can add dependencies" })] }) }), _jsx("div", { className: "col-span-1", children: _jsx(Button, { size: "icon", className: "h-[29px] w-[29px]", onClick: submitAddProjectDependency, disabled: !canManage ||
                                                    savingProjectDependency ||
                                                    !dependencyProjectId ||
                                                    !selectedProject?.project.parentProjectId, children: "+" }) })] })] })) : null, _jsx("div", { className: "grid gap-2", children: _jsxs(Button, { type: "button", variant: "ghost", className: "h-auto justify-between px-0 py-0 text-left hover:bg-transparent", onClick: () => setShowMembers((value) => !value), children: [_jsxs("div", { className: "grid gap-1 text-left", children: [_jsx("div", { className: "text-sm font-medium", children: "Members" }), _jsx("div", { className: "text-muted-foreground text-xs", children: "Owners can add users or roles to this project." })] }), _jsx(ChevronRight, { strokeWidth: 1, className: `h-4 w-4 shrink-0 transition-transform ${showMembers ? "rotate-90" : ""}` })] }) }), showMembers ? (_jsxs(_Fragment, { children: [_jsx("div", { className: "max-h-72 overflow-auto rounded-md border", children: loading ? (_jsx("div", { className: "text-muted-foreground p-3 text-sm", children: "Loading\u2026" })) : members.length === 0 ? (_jsx("div", { className: "text-muted-foreground p-3 text-sm", children: "No members" })) : (_jsx("div", { className: "divide-y", children: members.map((m) => (_jsxs("div", { className: "flex items-center justify-between gap-2 p-3", children: [_jsxs("div", { className: "min-w-0", children: [_jsx("div", { className: "truncate text-sm font-medium", children: m.memberIdentifier }), _jsxs("div", { className: "text-muted-foreground truncate text-xs", children: [m.memberType, " \u2022 ", m.permission] })] }), _jsx(Button, { variant: "secondary", onClick: () => submitRemove(m.memberId), disabled: !canManage, children: "Remove" })] }, m.memberId))) })) }), _jsxs("div", { className: "grid grid-cols-12 items-end gap-2", children: [_jsx("div", { className: "col-span-3", children: _jsxs("div", { className: "grid gap-1.5", children: [_jsx(Label, { className: "text-xs font-medium", children: "Type" }), _jsx(Select, { value: memberType, onValueChange: (v) => setMemberType(v), options: [
                                                            { value: "User", label: "User" },
                                                            { value: "Role", label: "Role" },
                                                        ] })] }) }), _jsx("div", { className: "col-span-5", children: _jsxs("div", { className: "grid gap-1.5", children: [_jsx(Label, { className: "text-xs font-medium", children: "Identifier" }), _jsx(Input, { className: "h-[29px]", value: memberIdentifier, onChange: (e) => setMemberIdentifier(e.target.value), placeholder: memberType === "User"
                                                            ? "sitecore\\john"
                                                            : "sitecore\\Author" })] }) }), _jsx("div", { className: "col-span-3", children: _jsxs("div", { className: "grid gap-1.5", children: [_jsx(Label, { className: "text-xs font-medium", children: "Permission" }), _jsx(Select, { value: permission, onValueChange: (v) => setPermission(v), options: [
                                                            { value: "Viewer", label: "Viewer" },
                                                            { value: "Editor", label: "Editor" },
                                                            { value: "Owner", label: "Owner" },
                                                        ] })] }) }), _jsx("div", { className: "col-span-1", children: _jsx(Button, { size: "icon", className: "h-[29px] w-[29px]", onClick: submitAdd, disabled: !canManage, children: "+" }) })] })] })) : null] }) }), _jsxs(DialogFooter, { className: "border-border-default flex flex-col gap-3 border-t p-4 sm:flex-row sm:items-center sm:justify-between", children: [_jsx("div", { children: onDeleteProject && projectId ? (_jsxs(Button, { type: "button", variant: "ghost", className: "text-neutral-grey-100 hover:text-neutral-grey-100", onClick: () => onDeleteProject(projectId, selectedProject?.project.title ?? titleInput.trim()), disabled: !canDeleteProject || savingProject, "data-testid": "taskboard-project-settings-delete-project", children: [_jsx(DeleteIcon, { size: "lg" }), "Delete project"] })) : null }), _jsxs("div", { className: "flex flex-col-reverse gap-2 sm:flex-row sm:justify-end", children: [onClose ? (_jsx(Button, { variant: "outline", onClick: onClose, children: "Close" })) : null, _jsx(Button, { onClick: submitProjectSettings, disabled: !canManage || savingProject || !titleInput.trim(), children: savingProject ? "Saving..." : "Save Changes" })] })] })] }));
}
export function ProjectSettingsDialog(props) {
    const { open, onOpenChange, projectId, selectedProject, projects, onChanged, canOpenSourceTemplate = false, onOpenSourceTemplate, onDeleteProject, } = props;
    const title = useMemo(() => selectedProject?.project.title ?? "Project", [selectedProject]);
    return (_jsx(Dialog, { open: open, onOpenChange: onOpenChange, children: _jsxs(DialogContent, { className: "max-w-2xl", children: [_jsx(StyledDialogTitle, { icon: _jsx(Settings, { strokeWidth: 1 }), title: "Project Settings", subtitle: title }), _jsx(ProjectSettingsPanel, { active: open, projectId: projectId, selectedProject: selectedProject, projects: projects, onChanged: onChanged, canOpenSourceTemplate: canOpenSourceTemplate, onOpenSourceTemplate: onOpenSourceTemplate, onDeleteProject: onDeleteProject, onSaved: () => onOpenChange(false), onClose: () => onOpenChange(false), className: "border-0" })] }) }));
}
//# sourceMappingURL=ProjectSettingsDialog.js.map