import type { TextEditor, Uri } from 'vscode';
import { RemoteResourceType } from '@gitlens/git/models/remoteResource.js';
import { getBranchNameWithoutRemote, getRemoteNameFromBranchName } from '@gitlens/git/utils/branch.utils.js';
import { Logger } from '@gitlens/utils/logger.js';
import type { Container } from '../container.js';
import { GitUri } from '../git/gitUri.js';
import { showGenericErrorMessage } from '../messages.js';
import { getBestRepositoryOrShowPicker } from '../quickpicks/repositoryPicker.js';
import { command, executeCommand } from '../system/-webview/command.js';
import { ActiveEditorCommand } from './commandBase.js';
import { getCommandUri } from './commandBase.utils.js';
import type { OpenOnRemoteCommandArgs } from './openOnRemote.js';

@command()
export class OpenCurrentBranchOnRemoteCommand extends ActiveEditorCommand {
	constructor(private readonly container: Container) {
		super('gitlens.openCurrentBranchOnRemote');
	}

	async execute(editor?: TextEditor, uri?: Uri): Promise<void> {
		uri = getCommandUri(uri, editor);

		const gitUri = uri != null ? await GitUri.fromUri(uri) : undefined;

		const repository = await getBestRepositoryOrShowPicker(
			this.container,
			gitUri,
			editor,
			'Open Current Branch Name',
		);
		if (repository == null) return;

		try {
			const branch = await repository.git.branches.getBranch();
			if (branch?.detached) {
				void (await executeCommand<OpenOnRemoteCommandArgs>('gitlens.openOnRemote', {
					resource: {
						type: RemoteResourceType.Commit,
						sha: branch.sha ?? 'HEAD',
					},
					repoPath: repository.path,
				}));

				return;
			}

			let branchName;
			let remoteName;
			if (branch?.upstream != null && !branch.upstream.missing) {
				branchName = getBranchNameWithoutRemote(branch.upstream.name);
				remoteName = getRemoteNameFromBranchName(branch.upstream.name);
			} else if (branch != null) {
				branchName = branch.name;
			}

			void (await executeCommand<OpenOnRemoteCommandArgs>('gitlens.openOnRemote', {
				resource: {
					type: RemoteResourceType.Branch,
					branch: branchName ?? 'HEAD',
				},
				remote: remoteName,
				repoPath: repository.path,
			}));
		} catch (ex) {
			Logger.error(ex, 'OpenCurrentBranchOnRemoteCommand');
			void showGenericErrorMessage('Unable to open branch on remote provider');
		}
	}
}
