import { useContext, useEffect, useState, useRef } from 'react';
import {
  searchNamespaces,
  topLevelNamespaces,
} from '../pages/NamespacePage/namespaceOptions';
import DJClientContext from '../providers/djclient';
import {
  secondaryButtonStyle as buttonStyle,
  primaryButtonStyle,
  onSecondaryHover,
  onSecondaryOut,
} from './buttonStyles';
import {
  GitSettingsModal,
  CreateBranchModal,
  SyncToGitModal,
  CreatePRModal,
  DeleteBranchModal,
} from './git';
import { detectShape } from './git/gitShape';
import GitMenu from './GitMenu';

export default function NamespaceHeader({
  namespace,
  children,
  onGitConfigLoaded,
  onReadOnlyChange,
  namespaceOptions,
  currentNamespace,
}) {
  const djClient = useContext(DJClientContext).DataJunctionAPI;
  const [sources, setSources] = useState(null);
  const [recentDeployments, setRecentDeployments] = useState([]);
  const [deploymentsDropdownOpen, setDeploymentsDropdownOpen] = useState(false);
  const dropdownRef = useRef(null);

  // Git config state
  const [gitConfig, setGitConfig] = useState(null);
  const [gitConfigLoading, setGitConfigLoading] = useState(true);
  const [parentGitConfig, setParentGitConfig] = useState(null);
  const [existingPR, setExistingPR] = useState(null);
  const [prLoading, setPrLoading] = useState(false);

  // Branch switcher state
  const [branches, setBranches] = useState([]);
  const [branchDropdownOpen, setBranchDropdownOpen] = useState(false);
  const branchDropdownRef = useRef(null);

  // Namespace switcher state (opt-in: only active when namespaceOptions is provided)
  const [nsSwitcherOpen, setNsSwitcherOpen] = useState(false);
  const [nsQuery, setNsQuery] = useState('');
  const nsSwitcherRef = useRef(null);

  // Modal states
  const [showGitSettings, setShowGitSettings] = useState(false);
  const [showCreateBranch, setShowCreateBranch] = useState(false);
  const [showSyncToGit, setShowSyncToGit] = useState(false);
  const [showCreatePR, setShowCreatePR] = useState(false);
  const [showDeleteBranch, setShowDeleteBranch] = useState(false);

  useEffect(() => {
    // Reset loading state when namespace changes
    setGitConfigLoading(true);
    setPrLoading(false);
    setExistingPR(null);

    const fetchData = async () => {
      if (!namespace) {
        if (onGitConfigLoaded) onGitConfigLoaded(null);
        setGitConfigLoading(false);
        return;
      }
      if (namespace) {
        // Fetch deployment sources
        try {
          const data = await djClient.namespaceSources(namespace);
          setSources(data);

          try {
            const deployments = await djClient.listDeployments(namespace, 5);
            setRecentDeployments(deployments || []);
          } catch (err) {
            console.error('Failed to fetch deployments:', err);
            setRecentDeployments([]);
          }
        } catch (e) {
          // Silently fail - badge just won't show
        }

        // Fetch git config
        try {
          const config = await djClient.getNamespaceGitConfig(namespace);
          setGitConfig(config);
          if (onGitConfigLoaded) {
            onGitConfigLoaded(config);
          }

          // If this namespace is inside a branch (or IS the branch), fetch
          // parent/branches/PR.
          const branchNs = config?.branch_namespace;
          if (branchNs) {
            // The branch namespace itself carries the parent_namespace FK to
            // the git root. If this is a subnamespace, fetch the branch's
            // config to get that FK; otherwise the current config already
            // has it.
            const branchConfig =
              branchNs === namespace
                ? config
                : await djClient
                    .getNamespaceGitConfig(branchNs)
                    .catch(() => null);
            const gitRootNs = branchConfig?.parent_namespace;

            if (gitRootNs) {
              try {
                const parentConfig = await djClient.getNamespaceGitConfig(
                  gitRootNs,
                );
                setParentGitConfig(parentConfig);
              } catch (e) {
                console.error('Failed to fetch parent git config:', e);
              }

              try {
                const branchList = await djClient.getNamespaceBranches(
                  gitRootNs,
                );
                setBranches(branchList || []);
              } catch (e) {
                console.error('Failed to fetch branches:', e);
              }
            }

            // Check for existing PR scoped to the branch, not the current
            // (sub)namespace — a branch has at most one PR regardless of
            // which subnamespace page the user is on.
            setPrLoading(true);
            try {
              const pr = await djClient.getPullRequest(branchNs);
              setExistingPR(pr);
            } catch (e) {
              // No PR or error - that's fine
              setExistingPR(null);
            } finally {
              setPrLoading(false);
            }
          }
        } catch (e) {
          // Git config not available
          setGitConfig(null);
          if (onGitConfigLoaded) {
            onGitConfigLoaded(null);
          }
        } finally {
          setGitConfigLoading(false);
        }
      }
    };
    fetchData();
  }, [djClient, namespace]);

  // Close dropdowns when clicking outside
  useEffect(() => {
    const handleClickOutside = event => {
      if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
        setDeploymentsDropdownOpen(false);
      }
      if (
        branchDropdownRef.current &&
        !branchDropdownRef.current.contains(event.target)
      ) {
        setBranchDropdownOpen(false);
      }
      if (
        nsSwitcherRef.current &&
        !nsSwitcherRef.current.contains(event.target)
      ) {
        setNsSwitcherOpen(false);
      }
    };
    document.addEventListener('mousedown', handleClickOutside);
    return () => document.removeEventListener('mousedown', handleClickOutside);
  }, []);

  const namespaceParts = namespace ? namespace.split('.') : [];

  // ``branch_namespace`` is the branch this namespace belongs to (equals the
  // namespace when called against the branch itself, the ancestor branch when
  // called against a descendant).
  // isInBranch = "this lives under a branch" (used to show branch-scoped git
  // controls on subnamespaces too).
  const branchNamespace = gitConfig?.branch_namespace || null;
  const isInBranch = !!branchNamespace;
  const branchScopeNamespace = branchNamespace || namespace;
  // Descendants inherit github_repo_path via cascade, so compare against
  // git_root_namespace to know if this namespace IS the git root.
  const isGitRoot =
    gitConfig?.github_repo_path && gitConfig?.git_root_namespace === namespace;

  // Handlers for git operations
  const handleSaveGitConfig = async config => {
    const result = await djClient.updateNamespaceGitConfig(
      gitConfigOwnerNamespace,
      config,
    );
    if (!result?._error) {
      if (isBranch) setParentGitConfig(prev => ({ ...prev, ...result }));
      else setGitConfig(result);
    }
    return result;
  };
  const handleRemoveGitConfig = async () => {
    if (
      !window.confirm(
        'Remove this git config binding? If this namespace is still being deployed from git by CI, it will remain read-only. This does not delete any nodes or repo files.',
      )
    )
      return;
    const result = await djClient.deleteNamespaceGitConfig(
      gitConfigOwnerNamespace,
    );
    if (!result?._error) {
      if (isBranch) setParentGitConfig(null);
      else setGitConfig(null);
    }
  };

  // Branches are always created under the git root, forking from its default
  // branch — whether we're viewing the root itself or one of its branches (on a
  // branch page the root is carried by git_root_namespace / parentGitConfig).
  const gitRootNamespace = gitConfig?.git_root_namespace || namespace;

  const rootDefaultBranch = isGitRoot
    ? gitConfig?.default_branch
    : parentGitConfig?.default_branch;
  const canCreateBranch = !!(gitRootNamespace && rootDefaultBranch);

  const handleCreateBranch = async branchName => {
    return await djClient.createBranch(gitRootNamespace, branchName);
  };

  // Sync/PR operations always target the whole branch namespace, even
  // when invoked from a subnamespace page.
  const handleSyncToGit = async commitMessage => {
    return await djClient.syncNamespaceToGit(
      branchScopeNamespace,
      commitMessage,
    );
  };

  const handleCreatePR = async (title, body, onProgress) => {
    // First sync changes to git using PR title as commit message
    if (onProgress) onProgress('syncing');
    const syncResult = await djClient.syncNamespaceToGit(
      branchScopeNamespace,
      title,
    );
    if (syncResult?._error) {
      return syncResult;
    }

    // Then create the PR
    if (onProgress) onProgress('creating');
    const result = await djClient.createPullRequest(
      branchScopeNamespace,
      title,
      body,
    );
    if (result && !result._error) {
      setExistingPR(result);
    }
    return result;
  };

  const handleDeleteBranch = async deleteGitBranch => {
    return await djClient.deleteBranch(
      gitConfig.parent_namespace,
      namespace,
      deleteGitBranch,
    );
  };

  // Git state derivations
  const gitShape = detectShape(gitConfig || {});
  // Read-only follows the branch, not the resolved config's flat/root shape.
  // A sub-namespace inside a feature branch resolves as `flat` (it inherits
  // github_repo_path + git_branch from the branch but carries no
  // parent_namespace of its own), so the shape test alone wrongly locks
  // editable feature branches — the actual regression here. Instead: content
  // on the repo's default branch, on a git root, or in a 1:1 flat namespace is
  // read-only; a non-default (feature) branch and its sub-namespaces are
  // editable. `rootDefaultBranch` is resolved above from the git root's config
  // (parentGitConfig), which has finished loading by the time the verdict fires
  // below — setGitConfigLoading(false) runs after that fetch.
  const onSubBranch = !!branchNamespace && branchNamespace !== gitRootNamespace;
  const isDefaultBranch = onSubBranch
    ? gitConfig?.git_branch === rootDefaultBranch
    : gitShape === 'root' || gitShape === 'flat';
  const isReadOnly = !!gitConfig?.git_only || isDefaultBranch;
  const isGitDeployed =
    !!sources &&
    sources.total_deployments > 0 &&
    sources.primary_source?.type === 'git';
  // A non-default (feature) branch and its sub-namespaces stay editable even
  // when git-deployed — editing then syncing back is the point. The
  // git-deployed lock only applies elsewhere (default branch, 1:1 flat, git
  // root, or an unrecognized-but-git-deployed shape), which `isReadOnly`
  // already covers for the recognized cases.
  const isFeatureBranch = onSubBranch && !isDefaultBranch;
  const isGitManaged = isReadOnly || (isGitDeployed && !isFeatureBranch);
  // Repo config is owned by the git root. On a branch, edits target the root
  // (its config is parentGitConfig — branches sit one level below the root); a
  // flat or plain namespace owns its own config. This keeps flat namespaces
  // (e.g. magnesium.tech, no parent) editing themselves.
  const isBranch = gitShape === 'branch';
  const gitConfigOwnerNamespace = isBranch ? gitRootNamespace : namespace;
  const gitConfigOwnerConfig = isBranch ? parentGitConfig : gitConfig;
  // Report the read-only verdict only once it's actually known (git config +
  // sources loaded). Firing a premature `false` on mount makes consumers flash
  // editable UI (e.g. the node edit form) before the real verdict arrives.
  useEffect(() => {
    if (onReadOnlyChange && !gitConfigLoading) onReadOnlyChange(!!isGitManaged);
  }, [isGitManaged, gitConfigLoading, onReadOnlyChange]);

  const viewInGitUrl = () => {
    const repo = gitConfig?.github_repo_path;
    if (!repo) return null;
    const branch = gitConfig?.git_branch || gitConfig?.default_branch || 'main';
    const path = gitConfig?.git_path
      ? `/${gitConfig.git_path.replace(/^\/|\/$/g, '')}`
      : '';
    return `https://github.netflix.net/${repo}/tree/${branch}${path}`;
  };

  return (
    <>
      <style>
        {`
          @keyframes spin {
            from { transform: rotate(0deg); }
            to { transform: rotate(360deg); }
          }
        `}
      </style>
      <div
        style={{
          display: 'flex',
          justifyContent: 'space-between',
          alignItems: 'center',
          // Wrap so the action buttons drop below the breadcrumb on narrow
          // screens instead of overflowing / being clipped off the right edge.
          flexWrap: 'wrap',
          gap: '8px',
          padding: '12px 12px 12px 20px',
          marginBottom: '16px',
          borderTop: '1px solid #e2e8f0',
          borderBottom: '1px solid #e2e8f0',
          background: '#ffffff',
        }}
      >
        <div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
          <a href="/" style={{ display: 'flex', alignItems: 'center' }}>
            <svg
              xmlns="http://www.w3.org/2000/svg"
              width="16"
              height="16"
              fill="currentColor"
              viewBox="0 0 16 16"
            >
              <path d="M8.186 1.113a.5.5 0 0 0-.372 0L1.846 3.5 8 5.961 14.154 3.5 8.186 1.113zM15 4.239l-6.5 2.6v7.922l6.5-2.6V4.24zM7.5 14.762V6.838L1 4.239v7.923l6.5 2.6zM7.443.184a1.5 1.5 0 0 1 1.114 0l7.129 2.852A.5.5 0 0 1 16 3.5v8.662a1 1 0 0 1-.629.928l-7.185 2.874a.5.5 0 0 1-.372 0L.63 13.09a1 1 0 0 1-.63-.928V3.5a.5.5 0 0 1 .314-.464L7.443.184z" />
            </svg>
          </a>
          <svg
            xmlns="http://www.w3.org/2000/svg"
            width="12"
            height="12"
            fill="#6c757d"
            viewBox="0 0 16 16"
          >
            <path
              fillRule="evenodd"
              d="M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z"
            />
          </svg>
          {namespace ? (
            namespaceParts.map((part, index, arr) => {
              const isLast = index === arr.length - 1;
              const cumulative = arr.slice(0, index + 1).join('.');
              const href = `/namespaces/${cumulative}`;
              // The branch crumb (the segment whose cumulative path equals the
              // branch namespace) becomes the branch switcher — at ANY depth, not
              // only when the URL is exactly the branch root (so it stays available
              // after drilling into sub-namespaces below the branch).
              const isBranchCrumb =
                isInBranch && cumulative === branchNamespace;
              return (
                <span
                  key={index}
                  style={{ display: 'flex', alignItems: 'center', gap: '8px' }}
                >
                  {/* The branch crumb becomes the branch switcher. The first
                      segment becomes a searchable namespace switcher when
                      namespaceOptions is provided (opt-in). */}
                  {isBranchCrumb ? (
                    <div
                      ref={branchDropdownRef}
                      style={{ position: 'relative' }}
                    >
                      <button
                        onClick={() => setBranchDropdownOpen(o => !o)}
                        style={{
                          display: 'flex',
                          alignItems: 'center',
                          gap: '4px',
                          padding: '0',
                          background: 'none',
                          border: 'none',
                          fontWeight: '400',
                          fontSize: 'inherit',
                          color: '#1e293b',
                          cursor: 'pointer',
                        }}
                      >
                        <svg
                          xmlns="http://www.w3.org/2000/svg"
                          width="12"
                          height="12"
                          viewBox="0 0 24 24"
                          fill="none"
                          stroke="#64748b"
                          strokeWidth="2"
                          strokeLinecap="round"
                          strokeLinejoin="round"
                        >
                          <line x1="6" y1="3" x2="6" y2="15" />
                          <circle cx="18" cy="6" r="3" />
                          <circle cx="6" cy="18" r="3" />
                          <path d="M18 9a9 9 0 0 1-9 9" />
                        </svg>
                        {part}
                        <span style={{ fontSize: '8px', color: '#94a3b8' }}>
                          {branchDropdownOpen ? '▲' : '▼'}
                        </span>
                      </button>

                      {branchDropdownOpen && (
                        <div
                          style={{
                            position: 'absolute',
                            top: '100%',
                            left: 0,
                            marginTop: '4px',
                            backgroundColor: 'white',
                            border: '1px solid #e2e8f0',
                            borderRadius: '8px',
                            boxShadow: '0 4px 12px rgba(0,0,0,0.12)',
                            zIndex: 1000,
                            minWidth: '180px',
                            overflow: 'hidden',
                          }}
                        >
                          <div
                            style={{
                              padding: '8px 12px 6px',
                              fontSize: '10px',
                              fontWeight: 600,
                              textTransform: 'uppercase',
                              letterSpacing: '0.05em',
                              color: '#94a3b8',
                              borderBottom: '1px solid #f1f5f9',
                            }}
                          >
                            <a
                              href={`/namespaces/${gitConfig.parent_namespace}`}
                              style={{
                                color: '#94a3b8',
                                textDecoration: 'none',
                              }}
                              onClick={() => setBranchDropdownOpen(false)}
                            >
                              {gitConfig.parent_namespace}
                            </a>
                          </div>
                          {branches.length === 0 ? (
                            <div
                              style={{
                                padding: '10px 12px',
                                fontSize: '12px',
                                color: '#94a3b8',
                              }}
                            >
                              No branches found
                            </div>
                          ) : (
                            branches.map(b => {
                              const isCurrent = b.namespace === namespace;
                              return (
                                <a
                                  key={b.namespace}
                                  href={`/namespaces/${b.namespace}`}
                                  onClick={() => setBranchDropdownOpen(false)}
                                  style={{
                                    display: 'flex',
                                    alignItems: 'center',
                                    justifyContent: 'space-between',
                                    padding: '8px 12px',
                                    fontSize: '13px',
                                    color: isCurrent ? '#1e40af' : '#1e293b',
                                    backgroundColor: isCurrent
                                      ? '#eff6ff'
                                      : 'white',
                                    textDecoration: 'none',
                                    borderBottom: '1px solid #f8fafc',
                                  }}
                                >
                                  <span
                                    style={{
                                      display: 'flex',
                                      alignItems: 'center',
                                      gap: '6px',
                                      minWidth: 0,
                                    }}
                                  >
                                    {isCurrent && (
                                      <svg
                                        xmlns="http://www.w3.org/2000/svg"
                                        width="10"
                                        height="10"
                                        viewBox="0 0 24 24"
                                        fill="none"
                                        stroke="currentColor"
                                        strokeWidth="3"
                                        strokeLinecap="round"
                                        strokeLinejoin="round"
                                        style={{ flexShrink: 0 }}
                                      >
                                        <polyline points="20 6 9 17 4 12" />
                                      </svg>
                                    )}
                                    <span
                                      style={{
                                        overflow: 'hidden',
                                        textOverflow: 'ellipsis',
                                        whiteSpace: 'nowrap',
                                        maxWidth: '180px',
                                      }}
                                      title={b.git_branch || b.namespace}
                                    >
                                      {b.git_branch || b.namespace}
                                    </span>
                                  </span>
                                  <span
                                    style={{
                                      fontSize: '11px',
                                      color: '#94a3b8',
                                      flexShrink: 0,
                                      marginLeft: '8px',
                                    }}
                                  >
                                    {b.num_nodes} nodes
                                  </span>
                                </a>
                              );
                            })
                          )}
                          {canCreateBranch && (
                            <button
                              onClick={() => {
                                setBranchDropdownOpen(false);
                                setShowCreateBranch(true);
                              }}
                              style={{
                                display: 'flex',
                                alignItems: 'center',
                                gap: '6px',
                                width: '100%',
                                padding: '10px 12px',
                                fontSize: '13px',
                                fontWeight: 500,
                                color: '#2563eb',
                                background: 'none',
                                border: 'none',
                                borderTop: '1px solid #f1f5f9',
                                cursor: 'pointer',
                                textAlign: 'left',
                              }}
                            >
                              <svg
                                xmlns="http://www.w3.org/2000/svg"
                                width="12"
                                height="12"
                                viewBox="0 0 24 24"
                                fill="none"
                                stroke="currentColor"
                                strokeWidth="2"
                                strokeLinecap="round"
                                strokeLinejoin="round"
                              >
                                <line x1="12" y1="5" x2="12" y2="19" />
                                <line x1="5" y1="12" x2="19" y2="12" />
                              </svg>
                              New branch
                            </button>
                          )}
                        </div>
                      )}
                    </div>
                  ) : index === 0 && namespaceOptions?.length > 0 ? (
                    <div ref={nsSwitcherRef} style={{ position: 'relative' }}>
                      <button
                        onClick={() => {
                          setNsSwitcherOpen(o => !o);
                          setNsQuery('');
                        }}
                        style={{
                          display: 'flex',
                          alignItems: 'center',
                          gap: '4px',
                          padding: '0',
                          background: 'none',
                          border: 'none',
                          fontWeight: '400',
                          fontSize: 'inherit',
                          color: '#1e293b',
                          cursor: 'pointer',
                        }}
                      >
                        {part}
                        <span style={{ fontSize: '8px', color: '#94a3b8' }}>
                          {nsSwitcherOpen ? '▲' : '▼'}
                        </span>
                      </button>

                      {nsSwitcherOpen && (
                        <div
                          style={{
                            position: 'absolute',
                            top: '100%',
                            left: 0,
                            marginTop: '4px',
                            backgroundColor: 'white',
                            border: '1px solid #e2e8f0',
                            borderRadius: '8px',
                            boxShadow: '0 4px 12px rgba(0,0,0,0.12)',
                            zIndex: 1000,
                            minWidth: '220px',
                            overflow: 'hidden',
                          }}
                        >
                          <div style={{ padding: '8px' }}>
                            <input
                              type="text"
                              value={nsQuery}
                              onChange={e => setNsQuery(e.target.value)}
                              placeholder="Find a namespace…"
                              autoFocus
                              style={{
                                width: '100%',
                                padding: '6px 8px',
                                fontSize: '12px',
                                border: '1px solid #e2e8f0',
                                borderRadius: '4px',
                                outline: 'none',
                                boxSizing: 'border-box',
                              }}
                            />
                          </div>
                          <div
                            style={{ maxHeight: '280px', overflowY: 'auto' }}
                          >
                            {(() => {
                              // Default list: top-level namespaces only (the
                              // switcher is for jumping between top-level areas;
                              // deeper levels are reached by drilling folders).
                              // Typing searches across ALL depths.
                              const results = nsQuery.trim()
                                ? searchNamespaces(namespaceOptions, nsQuery)
                                : topLevelNamespaces(namespaceOptions);
                              if (results.length === 0) {
                                return (
                                  <div
                                    style={{
                                      padding: '8px 12px',
                                      fontSize: '12px',
                                      color: '#94a3b8',
                                    }}
                                  >
                                    No namespaces match.
                                  </div>
                                );
                              }
                              return results.map(path => {
                                const isCurrent = path === currentNamespace;
                                return (
                                  <a
                                    key={path}
                                    href={`/namespaces/${path}`}
                                    onClick={() => setNsSwitcherOpen(false)}
                                    style={{
                                      display: 'block',
                                      padding: '7px 12px',
                                      fontSize: '13px',
                                      color: isCurrent ? '#1e40af' : '#1e293b',
                                      backgroundColor: isCurrent
                                        ? '#eff6ff'
                                        : 'white',
                                      textDecoration: 'none',
                                      borderBottom: '1px solid #f8fafc',
                                      fontWeight: isCurrent ? 600 : 400,
                                    }}
                                  >
                                    {path}
                                  </a>
                                );
                              });
                            })()}
                          </div>
                        </div>
                      )}
                    </div>
                  ) : (
                    <a
                      href={href}
                      style={{
                        fontWeight: '400',
                        color: '#1e293b',
                        textDecoration: 'none',
                      }}
                    >
                      {part}
                    </a>
                  )}
                  {!isLast && (
                    <svg
                      xmlns="http://www.w3.org/2000/svg"
                      width="12"
                      height="12"
                      fill="#94a3b8"
                      viewBox="0 0 16 16"
                    >
                      <path
                        fillRule="evenodd"
                        d="M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z"
                      />
                    </svg>
                  )}
                </span>
              );
            })
          ) : (
            <span style={{ fontWeight: '600', color: '#1e293b' }}>
              All Namespaces
            </span>
          )}

          {/* Git-only (read-only) indicator */}
          {isGitManaged && (
            <span
              style={{
                display: 'flex',
                alignItems: 'center',
                gap: '4px',
                padding: '2px 8px',
                backgroundColor: '#fef3c7',
                borderRadius: '12px',
                fontSize: '11px',
                color: '#92400e',
                marginLeft: '4px',
              }}
              title="This namespace is git-only. Changes must be made via git and deployed."
            >
              <svg
                xmlns="http://www.w3.org/2000/svg"
                width="12"
                height="12"
                viewBox="0 0 24 24"
                fill="none"
                stroke="currentColor"
                strokeWidth="2"
                strokeLinecap="round"
                strokeLinejoin="round"
              >
                <rect x="3" y="11" width="18" height="11" rx="2" ry="2" />
                <path d="M7 11V7a5 5 0 0 1 10 0v4" />
              </svg>
              Read-only
            </span>
          )}

          {/* Local deployment badge + dropdown (non-git deploys only;
              git deployments are surfaced in the status strip below) */}
          {sources &&
            sources.total_deployments > 0 &&
            sources.primary_source?.type !== 'git' && (
              <div
                style={{ position: 'relative', marginLeft: '8px' }}
                ref={dropdownRef}
              >
                <button
                  onClick={() =>
                    setDeploymentsDropdownOpen(!deploymentsDropdownOpen)
                  }
                  style={{
                    height: '32px',
                    padding: '0 12px',
                    fontSize: '12px',
                    border: 'none',
                    borderRadius: '4px',
                    backgroundColor: '#ffffff',
                    color: '#0b3d91',
                    cursor: 'pointer',
                    display: 'flex',
                    alignItems: 'center',
                    gap: '4px',
                    whiteSpace: 'nowrap',
                  }}
                >
                  <>
                    <svg
                      xmlns="http://www.w3.org/2000/svg"
                      width="12"
                      height="12"
                      viewBox="0 0 24 24"
                      fill="none"
                      stroke="currentColor"
                      strokeWidth="2"
                      strokeLinecap="round"
                      strokeLinejoin="round"
                    >
                      <circle cx="12" cy="7" r="4" />
                      <path d="M5.5 21a6.5 6.5 0 0 1 13 0Z" />
                    </svg>
                    Local Deploy
                  </>
                  <span style={{ fontSize: '8px' }}>
                    {deploymentsDropdownOpen ? '▲' : '▼'}
                  </span>
                </button>

                {deploymentsDropdownOpen && (
                  <div
                    style={{
                      position: 'absolute',
                      top: '100%',
                      left: 0,
                      marginTop: '4px',
                      padding: '12px',
                      backgroundColor: 'white',
                      border: '1px solid #ddd',
                      borderRadius: '8px',
                      boxShadow: '0 4px 12px rgba(0,0,0,0.15)',
                      zIndex: 1000,
                      minWidth: 'max-content',
                    }}
                  >
                    <div
                      style={{
                        display: 'flex',
                        alignItems: 'center',
                        gap: '8px',
                        fontSize: '13px',
                        fontWeight: 600,
                        color: '#0b3d91',
                        marginBottom: '12px',
                      }}
                    >
                      <svg
                        width="16"
                        height="16"
                        viewBox="0 0 24 24"
                        fill="none"
                        stroke="currentColor"
                        strokeWidth="2"
                        strokeLinecap="round"
                        strokeLinejoin="round"
                      >
                        <circle cx="12" cy="7" r="4" />
                        <path d="M5.5 21a6.5 6.5 0 0 1 13 0Z" />
                      </svg>
                      {recentDeployments?.[0]?.created_by
                        ? `Local deploys by ${recentDeployments[0].created_by}`
                        : 'Local/adhoc deployments'}
                    </div>

                    {/* Separator */}
                    <div
                      style={{
                        height: '1px',
                        backgroundColor: '#e2e8f0',
                        marginBottom: '8px',
                      }}
                    />

                    {/* Recent deployments list */}
                    {recentDeployments?.length > 0 ? (
                      recentDeployments.map((d, idx) => {
                        const isGit = d.source?.type === 'git';
                        const statusColor =
                          d.status === 'success'
                            ? '#22c55e'
                            : d.status === 'failed'
                            ? '#ef4444'
                            : '#94a3b8';

                        const commitUrl =
                          isGit && d.source?.repository && d.source?.commit_sha
                            ? `${
                                d.source.repository.startsWith('http')
                                  ? d.source.repository
                                  : `https://${d.source.repository}`
                              }/commit/${d.source.commit_sha}`
                            : null;

                        const detail = isGit
                          ? d.source?.branch || 'main'
                          : d.source?.reason || d.source?.hostname || 'adhoc';

                        const shortSha = d.source?.commit_sha?.slice(0, 7);

                        return (
                          <div
                            key={`${d.uuid}-${idx}`}
                            style={{
                              display: 'grid',
                              gridTemplateColumns: '18px 1fr auto',
                              alignItems: 'center',
                              gap: '8px',
                              padding: '6px 0',
                              borderBottom:
                                idx === recentDeployments.length - 1
                                  ? 'none'
                                  : '1px solid #f1f5f9',
                              fontSize: '12px',
                            }}
                          >
                            {/* Status dot */}
                            <div
                              style={{
                                width: '8px',
                                height: '8px',
                                borderRadius: '50%',
                                backgroundColor: statusColor,
                              }}
                              title={d.status}
                            />

                            {/* User + detail */}
                            <div
                              style={{
                                display: 'flex',
                                alignItems: 'center',
                                gap: '6px',
                                minWidth: 0,
                              }}
                            >
                              <span
                                style={{
                                  fontWeight: 500,
                                  color: '#0f172a',
                                  whiteSpace: 'nowrap',
                                }}
                              >
                                {d.created_by || 'unknown'}
                              </span>
                              <span style={{ color: '#cbd5e1' }}>—</span>
                              {isGit ? (
                                <>
                                  <span
                                    style={{
                                      color: '#64748b',
                                      whiteSpace: 'nowrap',
                                    }}
                                  >
                                    {detail}
                                  </span>
                                  {shortSha && (
                                    <>
                                      <span style={{ color: '#cbd5e1' }}>
                                        @
                                      </span>
                                      {commitUrl ? (
                                        <a
                                          href={commitUrl}
                                          target="_blank"
                                          rel="noopener noreferrer"
                                          style={{
                                            fontFamily: 'monospace',
                                            fontSize: '11px',
                                            color: '#3b82f6',
                                            textDecoration: 'none',
                                          }}
                                        >
                                          {shortSha}
                                        </a>
                                      ) : (
                                        <span
                                          style={{
                                            fontFamily: 'monospace',
                                            fontSize: '11px',
                                            color: '#64748b',
                                          }}
                                        >
                                          {shortSha}
                                        </span>
                                      )}
                                    </>
                                  )}
                                </>
                              ) : (
                                <span
                                  style={{
                                    color: '#64748b',
                                    overflow: 'hidden',
                                    textOverflow: 'ellipsis',
                                    whiteSpace: 'nowrap',
                                  }}
                                >
                                  {detail}
                                </span>
                              )}
                            </div>

                            {/* Timestamp */}
                            <span
                              style={{
                                color: '#94a3b8',
                                fontSize: '11px',
                                whiteSpace: 'nowrap',
                              }}
                            >
                              {new Date(d.created_at).toLocaleDateString()}
                            </span>
                          </div>
                        );
                      })
                    ) : (
                      <div style={{ color: '#94a3b8', fontSize: '12px' }}>
                        No recent deployments
                      </div>
                    )}
                  </div>
                )}
              </div>
            )}
        </div>

        {/* Right side: git actions + children */}
        <div
          style={{
            display: 'flex',
            alignItems: 'center',
            gap: '8px',
            // Let the buttons wrap among themselves, staying right-aligned, when
            // they can't fit on one line. marginLeft:auto keeps them right-
            // aligned even after they wrap onto their own row below the crumb.
            flexWrap: 'wrap',
            justifyContent: 'flex-end',
            marginLeft: 'auto',
          }}
        >
          {/* Git controls — one primary action per state + a Git ▾ menu for the
              rest. isGitManaged (read-only) is the master switch and overrides
              structural gitShape. */}
          {!gitConfigLoading &&
            namespace &&
            (() => {
              const repoBranch =
                gitConfig?.git_branch || gitConfig?.default_branch;
              const editableBranch = gitShape === 'branch' && !isGitManaged;
              const gitUrl = viewInGitUrl();

              // Read-only: fork to propose a change; everything else in the menu.
              if (isGitManaged) {
                return (
                  <>
                    {canCreateBranch && (
                      <button
                        style={primaryButtonStyle}
                        onClick={() => setShowCreateBranch(true)}
                      >
                        <svg
                          xmlns="http://www.w3.org/2000/svg"
                          width="14"
                          height="14"
                          viewBox="0 0 24 24"
                          fill="none"
                          stroke="currentColor"
                          strokeWidth="2"
                          strokeLinecap="round"
                          strokeLinejoin="round"
                        >
                          <line x1="12" y1="5" x2="12" y2="19" />
                          <line x1="5" y1="12" x2="19" y2="12" />
                        </svg>
                        New Branch
                      </button>
                    )}
                    <GitMenu
                      repoPath={gitConfig?.github_repo_path}
                      branch={repoBranch}
                      viewInGitUrl={gitUrl}
                      onOpenSettings={() => setShowGitSettings(true)}
                    />
                  </>
                );
              }

              // Editable working branch: the edit -> ship loop inline.
              if (editableBranch) {
                return (
                  <>
                    <button
                      style={buttonStyle}
                      onClick={() => setShowSyncToGit(true)}
                      onMouseOver={onSecondaryHover}
                      onMouseOut={onSecondaryOut}
                    >
                      <svg
                        xmlns="http://www.w3.org/2000/svg"
                        width="14"
                        height="14"
                        viewBox="0 0 24 24"
                        fill="none"
                        stroke="currentColor"
                        strokeWidth="2"
                        strokeLinecap="round"
                        strokeLinejoin="round"
                      >
                        <path d="M21 12a9 9 0 0 1-9 9m9-9a9 9 0 0 0-9-9m9 9H3m9 9a9 9 0 0 1-9-9m9 9c1.66 0 3-4.03 3-9s-1.34-9-3-9m0 18c-1.66 0-3-4.03-3-9s1.34-9 3-9m-9 9a9 9 0 0 1 9-9" />
                      </svg>
                      Sync to Git
                    </button>
                    {prLoading ? (
                      <button
                        style={{
                          ...buttonStyle,
                          cursor: 'default',
                          opacity: 0.6,
                        }}
                        disabled
                      >
                        <svg
                          xmlns="http://www.w3.org/2000/svg"
                          width="14"
                          height="14"
                          viewBox="0 0 24 24"
                          fill="none"
                          stroke="currentColor"
                          strokeWidth="2"
                          strokeLinecap="round"
                          strokeLinejoin="round"
                          style={{ animation: 'spin 1s linear infinite' }}
                        >
                          <path d="M21 12a9 9 0 1 1-6.219-8.56" />
                        </svg>
                        Checking PR...
                      </button>
                    ) : existingPR ? (
                      <a
                        href={existingPR.pr_url}
                        target="_blank"
                        rel="noopener noreferrer"
                        style={{
                          ...primaryButtonStyle,
                          textDecoration: 'none',
                          backgroundColor: '#16a34a',
                          borderColor: '#16a34a',
                        }}
                      >
                        <svg
                          xmlns="http://www.w3.org/2000/svg"
                          width="14"
                          height="14"
                          viewBox="0 0 24 24"
                          fill="none"
                          stroke="currentColor"
                          strokeWidth="2"
                          strokeLinecap="round"
                          strokeLinejoin="round"
                        >
                          <circle cx="18" cy="18" r="3" />
                          <circle cx="6" cy="6" r="3" />
                          <path d="M13 6h3a2 2 0 0 1 2 2v7" />
                          <line x1="6" y1="9" x2="6" y2="21" />
                        </svg>
                        View PR #{existingPR.pr_number}
                      </a>
                    ) : (
                      <button
                        style={primaryButtonStyle}
                        onClick={() => setShowCreatePR(true)}
                      >
                        <svg
                          xmlns="http://www.w3.org/2000/svg"
                          width="14"
                          height="14"
                          viewBox="0 0 24 24"
                          fill="none"
                          stroke="currentColor"
                          strokeWidth="2"
                          strokeLinecap="round"
                          strokeLinejoin="round"
                        >
                          <circle cx="18" cy="18" r="3" />
                          <circle cx="6" cy="6" r="3" />
                          <path d="M13 6h3a2 2 0 0 1 2 2v7" />
                          <line x1="6" y1="9" x2="6" y2="21" />
                        </svg>
                        Create PR
                      </button>
                    )}
                    <GitMenu
                      repoPath={gitConfig?.github_repo_path}
                      branch={repoBranch}
                      viewInGitUrl={gitUrl}
                      onNewBranch={
                        canCreateBranch && (() => setShowCreateBranch(true))
                      }
                      onDelete={() => setShowDeleteBranch(true)}
                    />
                  </>
                );
              }

              // Plain (not-git): a single entry to adopt git.
              return (
                <button
                  style={buttonStyle}
                  onClick={() => setShowGitSettings(true)}
                  onMouseOver={onSecondaryHover}
                  onMouseOut={onSecondaryOut}
                >
                  <svg
                    xmlns="http://www.w3.org/2000/svg"
                    width="14"
                    height="14"
                    viewBox="0 0 24 24"
                    fill="none"
                    stroke="currentColor"
                    strokeWidth="2"
                    strokeLinecap="round"
                    strokeLinejoin="round"
                  >
                    <line x1="6" y1="3" x2="6" y2="15" />
                    <circle cx="18" cy="6" r="3" />
                    <circle cx="6" cy="18" r="3" />
                    <path d="M18 9a9 9 0 0 1-9 9" />
                  </svg>
                  Connect to Git
                </button>
              );
            })()}

          {/* Additional actions passed as children */}
          {children}
        </div>

        {/* Modals */}
        <GitSettingsModal
          isOpen={showGitSettings}
          onClose={() => setShowGitSettings(false)}
          onSave={handleSaveGitConfig}
          onRemove={handleRemoveGitConfig}
          currentConfig={gitConfigOwnerConfig}
          namespace={gitConfigOwnerNamespace}
          nodeCount={0} // TODO: wire real node count
        />

        <CreateBranchModal
          isOpen={showCreateBranch}
          onClose={() => setShowCreateBranch(false)}
          onCreate={handleCreateBranch}
          namespace={gitRootNamespace}
          gitBranch={rootDefaultBranch}
          isGitRoot={true}
        />

        <SyncToGitModal
          isOpen={showSyncToGit}
          onClose={() => setShowSyncToGit(false)}
          onSync={handleSyncToGit}
          namespace={branchScopeNamespace}
          gitBranch={gitConfig?.git_branch}
          repoPath={gitConfig?.github_repo_path}
        />

        <CreatePRModal
          isOpen={showCreatePR}
          onClose={() => setShowCreatePR(false)}
          onCreate={handleCreatePR}
          namespace={branchScopeNamespace}
          gitBranch={gitConfig?.git_branch}
          parentBranch={
            parentGitConfig?.git_branch || parentGitConfig?.default_branch
          }
          repoPath={gitConfig?.github_repo_path}
        />

        <DeleteBranchModal
          isOpen={showDeleteBranch}
          onClose={() => setShowDeleteBranch(false)}
          onDelete={handleDeleteBranch}
          namespace={namespace}
          gitBranch={gitConfig?.git_branch}
          parentNamespace={gitConfig?.parent_namespace}
        />
      </div>
    </>
  );
}
