import { CommandUtils, Config as Config$1 } from '@dovenv/core';
import { PackageJSON } from '@dovenv/core/utils';
import * as _sizium_core from '@sizium/core';

type ConfigSuper = {
    /**
     * Name of the repository.
     *
     * @example "dovenv"
     */
    ID?: string;
    /**
     * GitHub user|org ID.
     */
    userID?: string;
    /**
     * URL of the repopository.
     *
     * @example "https://github.com/pigeonposse/dovenv"
     */
    URL?: string;
    /**
     * The URL of the project's homepage.
     *
     * @example "https://pigeonposse.com"
     */
    homepageURL?: string;
    /**
     * Tags or topics associated with the repository.
     *
     * @example [ "web", "api", "rest-api", "openapi", "library", "node", "js"]
     */
    tags?: string[];
    /**
     * Description of the repository.
     *
     * @example "This is a cool project"
     */
    desc?: string;
    /**
     * Workflow default inputs.
     */
    workflowDefaultInputs?: string;
    /**
     * Path to .github/workflows directory.
     */
    workflowsDir?: string;
    /**
     * Primary branch from the repository.
     *
     * @example "main"
     */
    defaultBranch?: string;
};

declare class Repo<C extends ConfigSuper = ConfigSuper> {
    protected utils: CommandUtils;
    opts: C | undefined;
    constructor({ opts, utils, }: {
        opts?: C;
        utils: CommandUtils;
    });
    protected onInit(): void;
    protected _existsLocalGit(): Promise<boolean>;
    initGH(): Promise<void>;
    init(): Promise<void>;
}

type GitConfig = ConfigSuper & {
    /** Commit configuration */
    commit?: {
        /**
         * Type of commit message.
         * Add types for your commits.
         *
         * @example
         * [
         *   {value: 'feat', title: 'A new feature'},
         *   {value: 'fix', title: 'A bug fix'}
         * ]
         */
        types?: Array<{
            value: string;
            title?: string;
            desc?: string;
        }>;
        /**
         * Scope of commit message.
         *
         * @example
         * [
         * 	{value: 'core'},
         * 	{value: 'package'},
         * 	{value: 'env'},
         * 	{value: 'all'}
         * ]
         */
        scopes?: Array<{
            value: string;
            title?: string;
            desc?: string;
        }>;
    };
    /** Pull configuration */
    pull?: unknown;
    /**Push configuration */
    push?: unknown;
    /**Husky configuration
     * @link https://typicode.github.io/husky/
     */
    husky?: {
        /**
         * The path to set the '.husky' directory.
         *
         * @default '.dovenv/.husky'
         */
        path: string;
    };
};

declare class GitSuper extends Repo<GitConfig> {
    getGitRemoteURL(): Promise<string | undefined>;
}

declare class GitAdd extends GitSuper {
    ask(initialValue?: string): Promise<string>;
    exec(value: string): Promise<void>;
    run(): Promise<void>;
}

declare class GitBranch extends GitSuper {
    #private;
    askSelectBranch(defaultValue?: string, remote?: boolean): Promise<string>;
    /**
     * Get the current branch name.
     *
     * @returns {Promise<string>} - The name of the current branch.
     */
    getCurrent(): Promise<string>;
    /**
     * Shows the current branch name.
     *
     * @returns {Promise<void>}
     */
    showCurrent(): Promise<void>;
    /**
     * Get all branches in the repository.
     *
     * @param   {boolean}           remote - If true, shows remote branches as well.
     * @returns {Promise<string[]>}        - An array of branch names.
     */
    getAll(remote?: boolean): Promise<string[]>;
    /**
     * Show all branches in the repository.
     *
     * @param   {boolean}       remote - If true, shows remote branches as well.
     * @returns {Promise<void>}
     */
    showAll(remote?: boolean): Promise<void>;
    /**
     * Change to a specified branch.
     *
     * @param   {string}        branchName - The name of the branch to switch to.
     * @param   {boolean}       force      - If true, force switches to the branch, discarding local changes.
     * @returns {Promise<void>}
     */
    change(branchName?: string, force?: boolean): Promise<void>;
    /**
     * Switch to an existing branch.
     *
     * @param   {string}        [branchName] - The name of the branch to switch to.
     * @returns {Promise<void>}
     */
    switch(branchName?: string): Promise<void>;
    /**
     * Create a new branch without switching to it.
     *
     * @param   {string}        [branchName] - The name of the branch to create.
     * @returns {Promise<void>}
     */
    create(branchName?: string): Promise<void>;
    /**
     * Create a new branch and switch to it.
     *
     * @param   {string}        [branchName] - The name of the branch to create and switch to.
     * @returns {Promise<void>}
     */
    createAndSwitch(branchName?: string): Promise<void>;
    /**
     * Delete a branch.
     *
     * @param   {string}        [branchName] - The name of the branch to delete.
     * @param   {boolean}       force        - If true, forces deletion of the branch.
     * @returns {Promise<void>}
     */
    delete(branchName?: string, force?: boolean): Promise<void>;
}

/**
 * See: https://github.com/commitizen/cz-cli?tab=readme-ov-file#1-create-your-own-entry-point-script.
 */

type Commit = Exclude<NonNullable<GitCommit['opts']>['commit'], undefined>;
declare class GitCommit extends GitSuper {
    types: Commit['types'];
    scopes: Commit['scopes'];
    getStagedFiles(): Promise<string>;
    /**
     * Get list of staged files.
     *
     * @returns {Promise<string[]>} List of staged files.
     */
    getStagedFilesList(): Promise<string[]>;
    /**
     * Get the last commit message.
     *
     * @returns {Promise<string>} The last commit message.
     */
    getLastCommit(): Promise<string>;
    isStageEmpty(): Promise<boolean>;
    exec(message: string): Promise<void>;
    ask(execute?: boolean): Promise<string>;
    run(): Promise<string | undefined>;
}

declare class Husky extends GitSuper {
    #private;
    run(): Promise<void>;
}

declare class GitInit extends GitSuper {
    #private;
    isInit(): Promise<boolean>;
    run(silent?: boolean): Promise<void>;
}

declare class GitPull extends GitSuper {
    #private;
    run(): Promise<void>;
}

declare class GitPush extends GitSuper {
    exec(branch: string): Promise<void>;
    run(opts?: {
        skipUpdate?: boolean;
        skipWorkflow?: boolean;
    }): Promise<void>;
}

declare class Git extends Repo<GitConfig> {
    add: GitAdd;
    branch: GitBranch;
    commit: GitCommit;
    husky: Husky;
    pull: GitPull;
    push: GitPush;
    initialize: GitInit;
    constructor(data: {
        opts?: GitConfig;
        utils: Repo['utils'];
    });
}
/**
 * Dovenv plugin for managing a repository.
 *
 * @param   {GitConfig}    [conf] - Optional configuration.
 * @returns {DovenvConfig}        - The plugin configuration.
 * @example
 * import { defineConfig } from '@dovenv/core'
 * import { gitPlugin } from '@dovenv/plugin/repo'
 *
 * export default defineConfig( [
 *   gitPlugin( {
 *     commit : {
 *       types : [
 *         { value: 'feat', title: 'A new feature' },
 *         { value: 'fix', title: 'A bug fix' },
 *       ],
 *       scopes : [
 *         { value: 'core', title: 'Core' },
 *         { value: 'package', title: 'Package' },
 *         { value: 'env', title: 'Environment' },
 *         { value: 'all', title: 'All' },
 *       ],
 *     },
 *   } ),
 * ] )
 */
declare const gitPlugin: (conf?: GitConfig) => Config$1;

declare class GHSuper extends Repo {
    getRepoList(opts?: {
        archived?: boolean;
        fork?: boolean;
        visibility?: 'public' | 'private' | 'internal';
    }): Promise<{
        desc: string | undefined;
        homepage: string | undefined;
        name: string;
        owner: string;
        topics: string[] | undefined;
        url: string;
    }[]>;
}

declare class GitHubCreate extends GHSuper {
    run(): Promise<void>;
}

declare class GitHubInfo extends GHSuper {
    viewAll(): Promise<void>;
    view(): Promise<void>;
    update(): Promise<void>;
}

declare class GitHubWorkflow extends GHSuper {
    list(): Promise<void>;
    run(): Promise<void>;
}

declare class GitHub {
    info: GitHubInfo;
    workflow: GitHubWorkflow;
    create: GitHubCreate;
    opts: ConfigSuper | undefined;
    protected utils: CommandUtils;
    constructor({ opts, utils, }: {
        opts?: ConfigSuper;
        utils: CommandUtils;
    });
    download(input: string, output: string): Promise<void>;
}
declare const ghPlugin: (conf?: ConfigSuper) => Config$1;

declare class Packages extends Repo {
    #private;
    init(): Promise<void>;
    publish(preCmd?: string): Promise<void>;
    version(): Promise<void>;
    prepare(): Promise<void>;
    getPkgVersion(npm?: boolean, showPrivate?: boolean): Promise<{
        name: string;
        version: string;
        npm: string | undefined;
        private: boolean;
    }[]>;
    showPackageVersion(npm?: boolean): Promise<void>;
    ask(): Promise<{}>;
    release(): Promise<void>;
    getSizeData(name?: string): Promise<{
        data: _sizium_core.SiziumResponse;
        inputType: "string" | "url" | "json" | "path";
    }>;
    getSize(name?: string): Promise<{
        data: _sizium_core.SiziumResponse;
        inputType: "string" | "url" | "json" | "path";
    }>;
}

declare const pkgPlugin: (conf?: ConfigSuper) => Config$1;

/**
 * Contributor roles object with their names and emojis.
 */
declare const CONTRIBUTOR_ROLE: {
    readonly author: {
        readonly name: "Author";
        readonly emoji: "👑";
        readonly desc: "Author of the project.";
    };
    readonly developer: {
        readonly name: "Developer";
        readonly emoji: "💻";
        readonly desc: "Contributor for the development of the project. Code, docs, etc.";
    };
    readonly contributor: {
        readonly name: "Contributor";
        readonly emoji: "💻";
        readonly desc: "Contributor for the development of the project. Code, docs, etc.";
    };
    readonly mantainer: {
        readonly name: "Mantainer";
        readonly emoji: "🚧";
        readonly desc: "Maintainer of the project. Code, docs, etc.";
    };
    readonly designer: {
        readonly name: "Designer";
        readonly emoji: "💄";
        readonly desc: "Contributor for the design of the project. Images, icons, etc.";
    };
    readonly organization: {
        readonly name: "Organization";
        readonly emoji: "🏢";
        readonly desc: "Organization of the project.";
    };
    readonly sponsor: {
        readonly name: "Sponsor";
        readonly emoji: "🤝";
        readonly desc: "Sponsor of the project.";
    };
    readonly translator: {
        readonly name: "Translator";
        readonly emoji: "🌏";
        readonly desc: "Translator for the project.";
    };
};

type RoleKey = string | number | symbol;
type RoleValue = {
    /** Name of the role */
    name: string;
    /** Emoji of the role */
    emoji: string;
    /** Description of the role */
    desc?: string;
};
type RoleMap = {
    [key: RoleKey]: RoleValue;
};
type Role = RoleMap;
type Members<ID extends RoleKey> = {
    /** Role id */
    role: ID;
    /**
       Github name id from user or organization.
     */
    ghUsername: string;
    /** Contributor name */
    name: string;
    /** Contributor avatar url */
    avatar?: string;
    /** Contributor profile url */
    url?: string;
}[];
type ContributorsRoledOpts<R extends Role> = {
    role?: R;
    member?: Members<keyof R>;
};
type ContributorsOpts = ContributorsRoledOpts<Role>;
type ContributorsParams<R extends Role> = {
    opts?: ContributorsRoledOpts<R>;
    utils?: CommandUtils;
};
type ContributorsConfig<R extends Role> = {
    /**
     * Set contributor roles.
     *
     * @example
     * {
     *     owner: { name: 'Owner', emoji: '👑' },
     *     developer: { name: 'Developer', emoji: '🤝' },
     *     organization: { name: 'Organization', emoji: '🏢' },
     *     sponsor: { name: 'Sponsor', emoji: '🤝' },
     *     translator: { name: 'Translator', emoji: '🌏' }
     * },
     */
    role: R;
    /**
     * Set contributor members.
     *
     * @example
     * [
     *     { ghUsername: 'angelespejo', name: 'Angelo', role: 'author' },
     *     { ghUsername: 'pigeonposse', name: 'PigeonPosse', role: 'organization' },
     *  ]
     */
    member: Members<keyof R>;
};

/**
 * Converts a package's author, contributors, and maintainers information into
 * a structured format of contributors and their roles.
 *
 * @param   {PackageJSON}      pkg    - The package JSON containing author, contributors, and maintainers data.
 * @param   {ContributorsOpts} [opts] - Optional contributors options.
 * @returns {object}                  An object containing:
 *                                    - `role`: An object defining various contributor roles with their names and emojis.
 *                                    - `member`: An array of contributors with details like role, GitHub username, name, and URL.
 */
declare const package2Contributors: (pkg: PackageJSON, opts?: ContributorsOpts) => ContributorsOpts | undefined;

/**
 * Dovenv plugin for managing workspace contributors.
 *
 * @param   {ContributorsConfig} [conf] - Optional configuration.
 * @returns {DovenvConfig}              - The plugin configuration.
 */
declare const contributorsPlugin: <R extends Role = Role>(conf?: ContributorsConfig<R>) => Config$1;

type ContributorsContentConfig = {
    /**
     * the name Column.
     *
     * @default true
     */
    name?: boolean;
    /**
     * the image Column.
     *
     * @default true
     */
    image?: boolean;
    /**
     * the role Column.
     *
     * @default true
     */
    role?: boolean;
};
type ContributorsGetOpts = ContributorsOpts & {
    content?: ContributorsContentConfig;
};
declare class Contributors<R extends RoleMap = Role> {
    opts: ContributorsOpts | undefined;
    protected utils: CommandUtils | undefined;
    constructor(config?: ContributorsParams<R>);
    /**
     * Filter the contributors by role using a list of role IDs.
     *
     * @param   {RoleKey[]}                             role - Role IDs to filter by.
     * @returns {Promise<ContributorsOpts | undefined>}      - The filtered contributors.
     */
    filterByRole(role: RoleKey[]): Promise<ContributorsOpts | undefined>;
    /**
     * Filter the contributors by role using a pattern.
     *
     * Uses the `getMatch` utility to filter the role IDs using the provided pattern.
     * The filtered role IDs are then passed to the `filterByRole` method.
     *
     * @param   {string[]}                              pattern - Pattern to filter the role IDs with.
     * @returns {Promise<ContributorsOpts | undefined>}         - The filtered contributors.
     */
    filterByRolePattern(pattern: string[]): Promise<ContributorsOpts | undefined>;
    /**
     * Converts the HTML content of the contributors table to Markdown.
     *
     * @param   {object}          [opts] - Options object.
     * @returns {Promise<string>}        - The Markdown content of the contributors table.
     */
    getMarkdownContent(opts?: ContributorsGetOpts): Promise<string>;
    /**
     * Retrieves the HTML content of a table containing the contributors.
     *
     * Optionally takes an object with the same shape as the class constructor options.
     * If the `role` or `member` properties are not provided, they default to the class constructor options.
     *
     * @param   {object}          [opts] - Options object.
     * @returns {Promise<string>}        - The HTML content of the contributors table.
     */
    getHtmlContent(opts?: ContributorsGetOpts): Promise<string>;
    /**
     * Retrieves the contributors table content formatted for the terminal.
     *
     * Optionally takes an object with the same shape as the class constructor options.
     * If the `role` or `member` properties are not provided, they default to the class constructor options.
     *
     * @param   {object}          [opts] - Options object.
     * @returns {Promise<string>}        - The terminal-formatted content of the contributors table.
     */
    getTerminalContent(opts?: ContributorsGetOpts): Promise<string>;
    /**
     * Logs the contributors table as a formatted string to the terminal.
     *
     * @param   {object}        [opts] - Options object.
     * @returns {Promise<void>}        - The result of logging the contributors table.
     */
    showTerminalOutput(opts?: ContributorsGetOpts): Promise<void>;
}

type Config<R extends Role> = ConfigSuper & GitConfig & {
    /** Contributors configuration */
    contributors?: ContributorsConfig<R>;
};
/**
 * Dovenv plugin for managing a repository.
 *
 * @param   {Config}       opts - Optional configuration.
 * @returns {DovenvConfig}      - The plugin configuration.
 */
declare const repoPlugin: <R extends Role = Role>(opts?: Config<R>) => Config$1;

export { CONTRIBUTOR_ROLE, Contributors, Git, GitAdd, GitBranch, GitCommit, GitHub, GitHubInfo, GitHubWorkflow, GitInit, GitPull, GitPush, Husky, Packages, contributorsPlugin, repoPlugin as default, ghPlugin, gitPlugin, package2Contributors, pkgPlugin, repoPlugin };
export type { Config, ContributorsConfig, GitConfig, ConfigSuper as GitHubConfig, Members, ConfigSuper as PackageConfig, Role };
