import { createInterface } from 'node:readline/promises';
import { stdin as input, stdout as output } from 'node:process';
import { createFrameworkMenuActions, type MenuAction } from './framework-menu-actions';
import {
  formatAdvancedMenuClassicView,
  formatAdvancedMenuView,
} from './framework-menu-advanced-view-lib';
import { createConsumerMenuRuntime } from './framework-menu-consumer-runtime-lib';
import {
  runRangeGate,
  runRepoAndStagedGate,
  runRepoAndStagedGateSilent,
  runRepoGateSilent,
  runRepoGateSilentWithBlocked,
  runStagedGate,
  runStagedGateSilent,
  runStagedGateSilentWithBlocked,
  runWorkingTreeGateSilent,
  runWorkingTreeGateSilentWithBlocked,
  runRepoAndStagedPrePushGateSilent,
  runWorkingTreePrePushGateSilent,
  runWorkingTreePrePushGateSilentWithBlocked,
  runUnstagedGateSilentWithBlocked,
} from './framework-menu-gate-lib';
import { createFrameworkMenuPrompts } from './framework-menu-prompts';
import { resolveDefaultRangeFrom } from './framework-menu-runners';
import {
  formatActiveSkillsBundles,
  loadAndFormatActiveSkillsBundles,
} from './framework-menu-skills-lib';
import { isMenuUiV2Enabled } from './framework-menu-ui-version-lib';
export * from './framework-menu-builders';
export { formatAdvancedMenuView } from './framework-menu-advanced-view-lib';
export { buildMenuGateParams } from './framework-menu-gate-lib';
export { formatActiveSkillsBundles } from './framework-menu-skills-lib';
type MenuMode = 'consumer' | 'advanced';

const printActiveSkillsBundles = (): void => {
  const rendered = loadAndFormatActiveSkillsBundles(process.cwd());
  output.write(`\n${rendered}\n`);
};

const resolveInitialMenuMode = (): MenuMode => {
  if (process.env.PUMUKI_MENU_MODE === 'advanced') {
    return 'advanced';
  }
  return 'consumer';
};

const menu = async (): Promise<void> => {
  const rl = createInterface({ input, output });

  try {
    let mode: MenuMode = resolveInitialMenuMode();
    const prompts = createFrameworkMenuPrompts(rl);
    const advancedActions: ReadonlyArray<MenuAction> = createFrameworkMenuActions({
      prompts,
      runStaged: runStagedGate,
      runRange: runRangeGate,
      runRepoAudit: runRepoGateSilent,
      runRepoAndStagedAudit: runRepoAndStagedGateSilent,
      runStagedAndUnstagedAudit: runWorkingTreeGateSilent,
      resolveDefaultRangeFrom,
      printActiveSkillsBundles,
    });
    const consumerRuntime = createConsumerMenuRuntime({
      runRepoGate: runRepoGateSilentWithBlocked,
      runRepoAndStagedGate: runRepoAndStagedPrePushGateSilent,
      runStagedGate: runStagedGateSilentWithBlocked,
      runUnstagedGate: runUnstagedGateSilentWithBlocked,
      runWorkingTreeGate: runWorkingTreePrePushGateSilentWithBlocked,
      runWorkingTreePreCommitGate: runWorkingTreeGateSilentWithBlocked,
      write: (text) => {
        output.write(text);
      },
    });

    while (true) {
      if (mode === 'consumer') {
        consumerRuntime.printMenu();
      } else {
        const currentSummary = consumerRuntime.readCurrentSummary();
        if (!isMenuUiV2Enabled()) {
          output.write(
            `\n${formatAdvancedMenuClassicView(advancedActions, {
              evidenceSummary: currentSummary ?? undefined,
            })}\n`
          );
        } else {
          try {
            output.write(
              `\n${formatAdvancedMenuView(advancedActions, {
                evidenceSummary: currentSummary ?? undefined,
              })}\n`
            );
          } catch {
            output.write('\n[pumuki][menu-ui-v2] Render failed. Falling back to classic menu.\n');
            output.write(
              `\n${formatAdvancedMenuClassicView(advancedActions, {
                evidenceSummary: currentSummary ?? undefined,
              })}\n`
            );
          }
        }
      }
      const prompt = mode === 'consumer' ? '\nChoose an option: ' : '\nSelect option: ';
      const option = (await rl.question(prompt)).trim();
      const normalized = option.toUpperCase();

      if (mode === 'consumer' && normalized === 'A') {
        mode = 'advanced';
        continue;
      }

      if (mode === 'advanced' && normalized === 'C') {
        mode = 'consumer';
        continue;
      }

      if (mode === 'consumer') {
        const selectedConsumer = consumerRuntime.actions.find((action) => action.id === option);
        if (!selectedConsumer) {
          output.write('Invalid option.\n');
          continue;
        }
        if (selectedConsumer.id === '10') {
          break;
        }
        try {
          await selectedConsumer.execute();
        } catch (error) {
          const message =
            error instanceof Error ? error.message : 'Unexpected menu execution error.';
          output.write(`Error: ${message}\n`);
        }
      } else {
        const selectedAdvanced = advancedActions.find((action) => action.id === option);
        if (!selectedAdvanced) {
          output.write('Invalid option.\n');
          continue;
        }
        if (selectedAdvanced.id === '27') {
          break;
        }
        try {
          await selectedAdvanced.execute();
        } catch (error) {
          const message =
            error instanceof Error ? error.message : 'Unexpected menu execution error.';
          output.write(`Error: ${message}\n`);
        }
      }
    }
  } finally {
    rl.close();
  }
};

export const runFrameworkMenu = async (): Promise<void> => {
  await menu();
};
