/**
 * start CLI execute — Execution logic, no validation
 */

import type { StartSpec, StartResult } from './types.js';
import { readConfig } from '../lib/config.js';
import { buildFullBranchName, getBaseBranch, normalizeBranchName } from '../lib/branch.js';
import { getWorktreePath } from '../lib/worktree.js';
import { branchExists, fetch, getCurrentBranch, checkout, push } from '../lib/git.js';

export async function execute(spec: StartSpec, cwd?: string): Promise<StartResult> {
  try {
    const config = await readConfig();
    const normalized = normalizeBranchName(spec.name);
    const fullBranch = buildFullBranchName(normalized, spec.type, config);
    const baseBranch = getBaseBranch(spec.type, config);

    if (await branchExists(fullBranch, false, cwd)) {
      return {
        success: false,
        error: `Branch ${fullBranch} already exists locally`,
        branch: fullBranch,
        branchType: spec.type,
        baseBranch,
        pushed: false,
      };
    }

    if (await branchExists(fullBranch, true, cwd)) {
      return {
        success: false,
        error: `Branch ${fullBranch} already exists on remote`,
        branch: fullBranch,
        branchType: spec.type,
        baseBranch,
        pushed: false,
      };
    }

    if (!spec.dryRun) {
      await fetch('origin', cwd);

      if (config.worktrees.enabled) {
        const wtPath = getWorktreePath(fullBranch, config);
        if (wtPath) {
          const { createWorktree } = await import('../lib/worktree.js');
          await createWorktree(fullBranch, wtPath, baseBranch, cwd);

          if (!spec.noPush) {
            await push(fullBranch, cwd, true);
          }

          return {
            success: true,
            branch: fullBranch,
            branchType: spec.type,
            baseBranch,
            worktreePath: wtPath,
            pushed: !spec.noPush,
          };
        }
      }

      await checkout(baseBranch, cwd);
      await checkout('-b', cwd);
      await checkout(fullBranch, cwd);

      if (!spec.noPush) {
        await push(fullBranch, cwd, true);
      }

      return {
        success: true,
        branch: fullBranch,
        branchType: spec.type,
        baseBranch,
        pushed: !spec.noPush,
      };
    }

    return {
      success: true,
      branch: fullBranch,
      branchType: spec.type,
      baseBranch,
      pushed: false,
    };
  } catch (err: unknown) {
    return {
      success: false,
      error: (err as Error).message,
      branch: '',
      branchType: spec.type,
      baseBranch: '',
      pushed: false,
    };
  }
}
