import React from 'react';
import {
  Select,
  SelectContent,
  SelectGroup,
  SelectItem,
  SelectLabel,
  SelectSeparator,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select';
import { useGitStore, useGitBranches, useGitLoadingBranches, useGitLoadingStatus, useIsGitRepo } from '@/stores/useGitStore';
import { useRuntimeAPIs } from '@/hooks/useRuntimeAPIs';
import { getRootBranch } from '@/lib/worktrees/worktreeStatus';
import { useI18n } from '@/lib/i18n';

/** localStorage key matching NewWorktreeDialog */
const LAST_SOURCE_BRANCH_KEY = 'oc:lastWorktreeSourceBranch';

export type WorktreeBaseOption = {
  value: string;
  label: string;
  group: 'special' | 'local' | 'remote';
};

export interface BranchSelectorProps {
  /** Current directory to check for git repository */
  directory: string | null;
  /** Currently selected branch */
  value: string;
  /** Called when branch selection changes */
  onChange: (branch: string) => void;
  /** Optional className for the trigger */
  className?: string;
  /** Whether the selector is disabled */
  disabled?: boolean;
  /** ID for accessibility */
  id?: string;
}

export interface BranchSelectorState {
  localBranches: string[];
  remoteBranches: string[];
  isLoading: boolean;
  isGitRepository: boolean | null;
}

/**
 * Hook to load available git branches for a directory.
 * Uses the shared useGitStore (same as NewWorktreeDialog).
 */
// eslint-disable-next-line react-refresh/only-export-components -- Hook is tightly coupled with BranchSelector
export function useBranchOptions(directory: string | null): BranchSelectorState {
  const { git } = useRuntimeAPIs();
  const branches = useGitBranches(directory);
  const isGitRepo = useIsGitRepo(directory);
  const isLoadingStatus = useGitLoadingStatus(directory);
  const isLoadingBranches = useGitLoadingBranches(directory);
  const fetchBranches = useGitStore((state) => state.fetchBranches);
  const fetchStatus = useGitStore((state) => state.fetchStatus);

  React.useEffect(() => {
    if (!directory || !git || isGitRepo !== null || isLoadingStatus) return;
    void fetchStatus(directory, git, { silent: true });
  }, [directory, git, fetchStatus, isGitRepo, isLoadingStatus]);

  // Fetch branches if not cached
  React.useEffect(() => {
    if (!directory || !git) return;
    if (isGitRepo !== true) return;
    if (branches?.all) return; // Already cached
    void fetchBranches(directory, git);
  }, [directory, git, isGitRepo, branches?.all, fetchBranches]);

  const isLoading = isLoadingStatus || (isGitRepo === true && isLoadingBranches);

  // Compute local and remote branch lists (same as NewWorktreeDialog)
  const localBranches = React.useMemo(() => {
    if (!branches?.all) return [];
    return branches.all
      .filter((branchName: string) => !branchName.startsWith('remotes/'))
      .sort();
  }, [branches]);

  const remoteBranches = React.useMemo(() => {
    if (!branches?.all) return [];
    return branches.all
      .filter((branchName: string) => branchName.startsWith('remotes/'))
      .map((branchName: string) => branchName.replace(/^remotes\//, ''))
      .sort();
  }, [branches]);

  // isGitRepository: true if we got branches, false if fetch returned empty, null if not yet loaded
  const isGitRepository = React.useMemo<boolean | null>(() => {
    if (!directory) return null;
    if (isGitRepo !== null) return isGitRepo;
    if (isLoading) return null;
    return branches?.all ? true : null;
  }, [directory, isLoading, branches, isGitRepo]);

  return { localBranches, remoteBranches, isLoading, isGitRepository };
}

/**
 * Branch selector dropdown for selecting a source branch for worktree creation.
 * Matches the NewWorktreeDialog source branch selector exactly.
 */
export const BranchSelector: React.FC<BranchSelectorProps> = ({
  directory,
  value,
  onChange,
  className,
  disabled,
  id,
}) => {
  const { t } = useI18n();
  const { localBranches, remoteBranches, isLoading, isGitRepository } = useBranchOptions(directory);
  const allBranches = React.useMemo(
    () => [...localBranches, ...remoteBranches.map(b => `remotes/${b}`)],
    [localBranches, remoteBranches],
  );

  // Resolve default source branch (same priority as NewWorktreeDialog)
  React.useEffect(() => {
    if (disabled || isLoading || allBranches.length === 0) return;
    // If current value is valid, keep it
    if (value && allBranches.includes(value)) return;

    const resolve = async () => {
      try {
        const rootBranch = directory ? await getRootBranch(directory).catch(() => null) : null;
        const saved = localStorage.getItem(LAST_SOURCE_BRANCH_KEY);

        if (saved && allBranches.includes(saved)) {
          onChange(saved);
        } else if (rootBranch && allBranches.includes(rootBranch)) {
          onChange(rootBranch);
        } else if (allBranches.includes('main')) {
          onChange('main');
        } else if (allBranches.includes('master')) {
          onChange('master');
        } else if (allBranches[0]) {
          onChange(allBranches[0]);
        }
      } catch {
        // ignore
      }
    };

    void resolve();
  }, [allBranches, directory, disabled, isLoading, onChange, value]);

  const isDisabled = disabled || !isGitRepository || isLoading;

  return (
    <div>
      <Select
        value={value}
        onValueChange={onChange}
        disabled={isDisabled}
      >
        <SelectTrigger
          id={id}
          size="lg"
          className={className ?? 'w-fit typography-meta text-foreground'}
        >
          <SelectValue placeholder={isLoading ? t('multiRun.branchSelector.status.loadingBranches') : t('multiRun.branchSelector.placeholder.selectSourceBranch')} />
        </SelectTrigger>
        <SelectContent className="max-h-[280px] max-w-[320px]">
          {isLoading ? (
            <div className="px-2 py-4 text-center typography-meta text-muted-foreground">
              {t('multiRun.branchSelector.status.loadingBranches')}
            </div>
          ) : localBranches.length === 0 && remoteBranches.length === 0 ? (
            <div className="px-2 py-4 text-center typography-meta text-muted-foreground">
              {t('multiRun.branchSelector.status.noBranchesFound')}
            </div>
          ) : (
            <>
              {localBranches.length > 0 && (
                <SelectGroup>
                  <SelectLabel className="font-semibold text-foreground">{t('multiRun.branchSelector.groups.localBranches')}</SelectLabel>
                  {localBranches.map((branch) => (
                    <SelectItem key={branch} value={branch} className="whitespace-normal break-all">
                      {branch}
                    </SelectItem>
                  ))}
                </SelectGroup>
              )}
              {localBranches.length > 0 && remoteBranches.length > 0 && (
                <SelectSeparator />
              )}
              {remoteBranches.length > 0 && (
                <SelectGroup>
                  <SelectLabel className="font-semibold text-foreground">{t('multiRun.branchSelector.groups.remoteBranches')}</SelectLabel>
                  {remoteBranches.map((branch) => (
                    <SelectItem key={`remotes/${branch}`} value={`remotes/${branch}`} className="whitespace-normal break-all">
                      {branch}
                    </SelectItem>
                  ))}
                </SelectGroup>
              )}
            </>
          )}
        </SelectContent>
      </Select>

      {isGitRepository === false && (
        <p className="typography-micro text-muted-foreground/70 mt-2">{t('multiRun.branchSelector.status.notInGitRepository')}</p>
      )}
    </div>
  );
};
