/**
 * SidebarHeader - Linear-style header with project name and worktree selector.
 *
 * Layout (2 stacked horizontal bars):
 * - Row 1: Project name (left-aligned after macOS traffic lights)
 * - Row 2: Worktree selector (full-width button)
 *
 * Visual requirements:
 * - Row 1 is the drag region for window movement
 * - Row 1 reserves left space for macOS traffic lights via shared layout CSS variable
 * - Row 2 is a full-width button with no side margins
 */

import { useEffect, useMemo, useRef, useState } from 'react';

import { isElectronMode } from '@renderer/api';
import { HEADER_ROW1_HEIGHT, HEADER_ROW2_HEIGHT } from '@renderer/constants/layout';
import { cn } from '@renderer/lib/utils';
import { useStore } from '@renderer/store';
import { formatShortcut, truncateMiddle } from '@renderer/utils/stringUtils';
import { Check, ChevronDown, GitBranch, PanelLeft } from 'lucide-react';
import { useShallow } from 'zustand/react/shallow';

import { AppLogo } from '../common/AppLogo';
import { WorktreeBadge } from '../common/WorktreeBadge';
import { Combobox, type ComboboxOption } from '../ui/combobox';

import type { Worktree, WorktreeSource } from '@renderer/types/data';

/**
 * Group worktrees by source for organized dropdown display.
 * Returns: main worktree first, then groups sorted by most recent activity.
 */
interface WorktreeGroup {
  source: WorktreeSource;
  label: string;
  worktrees: Worktree[];
  mostRecent: number;
}

const SOURCE_LABELS: Record<WorktreeSource, string> = {
  'vibe-kanban': 'Vibe Kanban',
  conductor: 'Conductor',
  'auto-claude': 'Auto Claude',
  '21st': '21st',
  'claude-desktop': 'Claude Desktop',
  ccswitch: 'ccswitch',
  git: 'Git',
  unknown: 'Other',
};

function groupWorktreesBySource(worktrees: Worktree[]): {
  mainWorktree: Worktree | null;
  groups: WorktreeGroup[];
} {
  // Find main worktree
  const mainWorktree = worktrees.find((w) => w.isMainWorktree) ?? null;

  // Group remaining worktrees by source
  const groupMap = new Map<WorktreeSource, Worktree[]>();

  for (const wt of worktrees) {
    if (wt.isMainWorktree) continue; // Skip main, handled separately

    const existing = groupMap.get(wt.source) ?? [];
    existing.push(wt);
    groupMap.set(wt.source, existing);
  }

  // Convert to array and sort each group internally by most recent
  const groups: WorktreeGroup[] = [];

  for (const [source, wts] of groupMap) {
    // Sort worktrees within group by most recent
    const sorted = [...wts].sort((a, b) => (b.mostRecentSession ?? 0) - (a.mostRecentSession ?? 0));

    const mostRecent = Math.max(...sorted.map((w) => w.mostRecentSession ?? 0));

    groups.push({
      source,
      label: SOURCE_LABELS[source] ?? source,
      worktrees: sorted,
      mostRecent,
    });
  }

  // Sort groups by most recent activity
  groups.sort((a, b) => b.mostRecent - a.mostRecent);

  return { mainWorktree, groups };
}

/**
 * Individual worktree item in the dropdown.
 */
interface WorktreeItemProps {
  worktree: Worktree;
  isSelected: boolean;
  onSelect: () => void;
}

const WorktreeItem = ({
  worktree,
  isSelected,
  onSelect,
}: Readonly<WorktreeItemProps>): React.JSX.Element => {
  const [isHovered, setIsHovered] = useState(false);

  const buttonStyle: React.CSSProperties = isSelected
    ? { backgroundColor: 'var(--color-surface-raised)', color: 'var(--color-text)' }
    : {
        backgroundColor: isHovered ? 'var(--color-surface-raised)' : 'transparent',
        opacity: isHovered ? 0.5 : 1,
      };

  return (
    <button
      onClick={onSelect}
      onMouseEnter={() => setIsHovered(true)}
      onMouseLeave={() => setIsHovered(false)}
      className="flex w-full items-center gap-1.5 px-4 py-1.5 text-left transition-colors"
      style={buttonStyle}
    >
      <GitBranch
        className="size-3.5 shrink-0"
        style={{ color: isSelected ? '#34d399' : 'var(--color-text-muted)' }}
      />
      {/* Only show badge for main worktree - others are grouped by header */}
      {worktree.isMainWorktree && <WorktreeBadge source={worktree.source} isMain />}
      <span
        className="flex-1 truncate font-mono text-xs"
        style={{ color: isSelected ? 'var(--color-text)' : 'var(--color-text-muted)' }}
      >
        {truncateMiddle(worktree.name, 28)}
      </span>
      <span className="shrink-0 text-[10px]" style={{ color: 'var(--color-text-muted)' }}>
        {worktree.sessions.length}
      </span>
      {isSelected && <Check className="size-3.5 shrink-0 text-indigo-400" />}
    </button>
  );
};

export const SidebarHeader = (): React.JSX.Element => {
  const isMacElectron =
    isElectronMode() && window.navigator.userAgent.toLowerCase().includes('mac');

  const {
    repositoryGroups,
    selectedRepositoryId,
    selectedWorktreeId,
    selectWorktree,
    selectRepository,
    viewMode,
    projects,
    activeProjectId,
    setActiveProject,
    clearActiveProject,
    fetchRepositoryGroups,
    fetchProjects,
    toggleSidebar,
  } = useStore(
    useShallow((s) => ({
      repositoryGroups: s.repositoryGroups,
      selectedRepositoryId: s.selectedRepositoryId,
      selectedWorktreeId: s.selectedWorktreeId,
      selectWorktree: s.selectWorktree,
      selectRepository: s.selectRepository,
      viewMode: s.viewMode,
      projects: s.projects,
      activeProjectId: s.activeProjectId,
      setActiveProject: s.setActiveProject,
      clearActiveProject: s.clearActiveProject,
      fetchRepositoryGroups: s.fetchRepositoryGroups,
      fetchProjects: s.fetchProjects,
      toggleSidebar: s.toggleSidebar,
    }))
  );

  // Fetch data on mount based on view mode
  useEffect(() => {
    if (viewMode === 'grouped' && repositoryGroups.length === 0) {
      void fetchRepositoryGroups();
    } else if (viewMode === 'flat' && projects.length === 0) {
      void fetchProjects();
    }
  }, [viewMode, repositoryGroups.length, projects.length, fetchRepositoryGroups, fetchProjects]);

  const [isWorktreeDropdownOpen, setIsWorktreeDropdownOpen] = useState(false);
  const worktreeDropdownRef = useRef<HTMLDivElement>(null);

  // Find the active repository and worktree
  const activeRepo = repositoryGroups.find((r) => r.id === selectedRepositoryId);
  const activeWorktree = activeRepo?.worktrees.find((w) => w.id === selectedWorktreeId);
  // Filter worktrees to only show those with sessions
  const worktrees = (activeRepo?.worktrees ?? []).filter((w) => w.sessions.length > 0);
  const hasMultipleWorktrees = worktrees.length > 1;

  // Group worktrees by source for organized dropdown
  const worktreeGroupingResult = groupWorktreesBySource(worktrees);
  const mainWorktree = worktreeGroupingResult.mainWorktree;
  const worktreeGroups = worktreeGroupingResult.groups;

  const worktreeName = activeWorktree?.name ?? 'main';

  const handleSelectWorktree = (worktree: Worktree): void => {
    selectWorktree(worktree.id);
    setIsWorktreeDropdownOpen(false);
  };

  const handleProjectValueChange = (id: string): void => {
    if (viewMode === 'grouped') selectRepository(id);
    else setActiveProject(id);
  };

  // Items for project combobox - filter out repositories/projects with 0 sessions
  const projectItems =
    viewMode === 'grouped'
      ? repositoryGroups.filter((r) => r.totalSessions > 0)
      : projects.filter((p) => p.sessions.length > 0);

  const projectComboboxOptions = useMemo((): ComboboxOption[] => {
    const items =
      viewMode === 'grouped'
        ? repositoryGroups.filter((r) => r.totalSessions > 0)
        : projects.filter((p) => p.sessions.length > 0);
    return items.map((item) => {
      const sessionCount =
        viewMode === 'grouped'
          ? (item as (typeof repositoryGroups)[0]).totalSessions
          : (item as (typeof projects)[0]).sessions.length;
      const path =
        viewMode === 'grouped'
          ? (item as (typeof repositoryGroups)[0]).worktrees[0]?.path
          : (item as (typeof projects)[0]).path;
      return {
        value: item.id,
        label: item.name,
        description: path,
        meta: { sessionCount, path },
      };
    });
  }, [viewMode, repositoryGroups, projects]);

  const activeProjectValue = viewMode === 'grouped' ? selectedRepositoryId : activeProjectId;

  const [isCollapseHovered, setIsCollapseHovered] = useState(false);

  return (
    <div
      className="flex w-full flex-col"
      style={{ backgroundColor: 'var(--color-surface-sidebar)' }}
    >
      {/* ROW 1: Logo in corner, project selector fills width, collapse button */}
      <div
        className="flex select-none items-center gap-1.5 pr-1"
        style={
          {
            height: `${HEADER_ROW1_HEIGHT}px`,
            paddingLeft: isMacElectron ? 'var(--macos-traffic-light-padding-left, 72px)' : 0,
            WebkitAppRegion: isMacElectron ? 'drag' : undefined,
          } as React.CSSProperties
        }
      >
        <div style={{ WebkitAppRegion: 'no-drag' } as React.CSSProperties}>
          <AppLogo size={22} className="shrink-0" />
        </div>
        <div
          className="min-w-0 flex-1"
          style={{ WebkitAppRegion: 'no-drag' } as React.CSSProperties}
        >
          <Combobox
            options={projectComboboxOptions}
            value={activeProjectValue ?? ''}
            onValueChange={handleProjectValueChange}
            placeholder="Select Project"
            searchPlaceholder="Search..."
            emptyMessage={
              projectItems.length === 0
                ? `No ${viewMode === 'grouped' ? 'repositories' : 'projects'} found`
                : 'Nothing found'
            }
            className="text-sm font-medium"
            resetLabel="Reset selection"
            onReset={clearActiveProject}
            renderOption={(option, isSelected) => {
              const sessionCount = (option.meta?.sessionCount as number) ?? 0;
              const path = option.meta?.path as string | undefined;
              return (
                <>
                  <Check
                    className={cn(
                      'mr-2 size-3.5 shrink-0',
                      isSelected ? 'text-indigo-400 opacity-100' : 'opacity-0'
                    )}
                  />
                  <div className="min-w-0 flex-1">
                    <p
                      className={cn(
                        'truncate',
                        isSelected
                          ? 'font-medium text-[var(--color-text)]'
                          : 'text-[var(--color-text-muted)]'
                      )}
                    >
                      {option.label}
                    </p>
                    {path ? (
                      <p className="truncate text-[10px] text-[var(--color-text-muted)]">{path}</p>
                    ) : null}
                  </div>
                  <span className="shrink-0 text-[10px] text-[var(--color-text-muted)]">
                    {sessionCount}
                  </span>
                </>
              );
            }}
          />
        </div>
        <button
          onClick={toggleSidebar}
          onMouseEnter={() => setIsCollapseHovered(true)}
          onMouseLeave={() => setIsCollapseHovered(false)}
          className="shrink-0 rounded-md p-1.5 transition-colors"
          style={
            {
              WebkitAppRegion: 'no-drag',
              color: isCollapseHovered ? 'var(--color-text-secondary)' : 'var(--color-text-muted)',
              backgroundColor: isCollapseHovered ? 'var(--color-surface-raised)' : 'transparent',
            } as React.CSSProperties
          }
          title={`Collapse sidebar (${formatShortcut('B')})`}
        >
          <PanelLeft className="size-4" />
        </button>
      </div>

      {/* ROW 2: Worktree Selector (Full Width) */}
      {viewMode === 'grouped' && activeRepo && (
        <div ref={worktreeDropdownRef} className="relative w-full">
          <button
            onClick={() =>
              hasMultipleWorktrees && setIsWorktreeDropdownOpen(!isWorktreeDropdownOpen)
            }
            disabled={!hasMultipleWorktrees}
            className={`flex w-full items-center justify-between px-4 text-left transition-colors ${hasMultipleWorktrees ? 'cursor-pointer' : 'cursor-default'}`}
            style={{
              height: `${HEADER_ROW2_HEIGHT}px`,
              backgroundColor: isWorktreeDropdownOpen
                ? 'var(--color-surface-raised)'
                : 'var(--color-surface-sidebar)',
              color: isWorktreeDropdownOpen ? 'var(--color-text)' : 'var(--color-text-muted)',
            }}
          >
            <div className="flex flex-1 items-center gap-1.5 overflow-hidden">
              <GitBranch
                className="size-4 shrink-0"
                style={{ color: isWorktreeDropdownOpen ? '#34d399' : 'rgba(52, 211, 153, 0.7)' }}
              />
              {activeWorktree?.isMainWorktree ? (
                <WorktreeBadge source={activeWorktree.source} isMain />
              ) : (
                activeWorktree?.source && <WorktreeBadge source={activeWorktree.source} />
              )}
              <span className="truncate font-mono text-xs">{truncateMiddle(worktreeName, 28)}</span>
            </div>
            {hasMultipleWorktrees && (
              <ChevronDown
                className={`size-4 shrink-0 transition-transform ${isWorktreeDropdownOpen ? 'rotate-180' : ''}`}
                style={{ color: 'var(--color-text-muted)' }}
              />
            )}
          </button>

          {/* Worktree Dropdown */}
          {isWorktreeDropdownOpen && hasMultipleWorktrees && (
            <>
              <div
                role="presentation"
                className="fixed inset-0 z-10"
                onClick={() => setIsWorktreeDropdownOpen(false)}
              />
              <div
                className="absolute inset-x-0 top-full z-20 mt-0 max-h-[400px] overflow-y-auto py-1 shadow-xl"
                style={{
                  backgroundColor: 'var(--color-surface-sidebar)',
                  borderWidth: '1px',
                  borderTopWidth: '0',
                  borderStyle: 'solid',
                  borderColor: 'var(--color-border)',
                }}
              >
                <div
                  className="px-4 py-2 text-[10px] font-semibold uppercase tracking-wider"
                  style={{ color: 'var(--color-text-muted)' }}
                >
                  Switch Worktree
                </div>

                {/* Main worktree first */}
                {mainWorktree && (
                  <WorktreeItem
                    worktree={mainWorktree}
                    isSelected={mainWorktree.id === selectedWorktreeId}
                    onSelect={() => handleSelectWorktree(mainWorktree)}
                  />
                )}

                {/* Grouped worktrees by source */}
                {worktreeGroups.map((group) => (
                  <div key={group.source}>
                    {/* Group header */}
                    <div
                      className="mt-1 px-4 py-1.5 text-[9px] font-medium uppercase tracking-wider"
                      style={{
                        borderTopWidth: '1px',
                        borderTopStyle: 'solid',
                        borderTopColor: 'var(--color-border)',
                        color: 'var(--color-text-muted)',
                      }}
                    >
                      {group.label}
                    </div>
                    {/* Worktrees in group */}
                    {group.worktrees.map((worktree) => (
                      <WorktreeItem
                        key={worktree.id}
                        worktree={worktree}
                        isSelected={worktree.id === selectedWorktreeId}
                        onSelect={() => handleSelectWorktree(worktree)}
                      />
                    ))}
                  </div>
                ))}
              </div>
            </>
          )}
        </div>
      )}
    </div>
  );
};
