import * as fs from 'fs';
import { program } from 'commander';
import yaml from 'yaml';
import * as shell from 'shelljs';
import chalk from 'chalk';
import { GitUtils } from '../utils/git.utils';

export class DocsPages {
  private DOCS_PAGES_STAGE = 'docs-pages';
  private DOCS_PAGES_INCLUDE = {
    project: 'infrastructure/gitlab-ci-templates',
    file: '/templates/docs-retype.yml',
  };
  private repoGitLabInfo?: { projectName?: string; groupName?: string; pagesUrl?: string };
  constructor() {}

  setup() {
    program
      .command('docs-pages')
      .description('Setup docs for GitLab pages')
      .action(async () => {
        if (GitUtils.logErrorIfNotInGitProject()) return;

        this.updateGitLabCi();
        this.repoGitLabInfo = this.getRepoInfo();
        this.mkdirDocs();
        this.logResult();
      });
  }
  private updateGitLabCi() {
    let gitlabCiYaml;

    const hasGitlabCi = fs.existsSync('.gitlab-ci.yml');
    if (!hasGitlabCi) {
      gitlabCiYaml = {};
    } else {
      gitlabCiYaml = yaml.parse(fs.readFileSync('./.gitlab-ci.yml').toString());
    }

    if (
      !(
        typeof gitlabCiYaml.stages?.includes === 'function' &&
        gitlabCiYaml.stages.includes(this.DOCS_PAGES_STAGE)
      )
    ) {
      gitlabCiYaml.stages = [...gitlabCiYaml.stages, this.DOCS_PAGES_STAGE];
    }

    if (
      !(
        typeof gitlabCiYaml.include?.find === 'function' &&
        gitlabCiYaml.include?.find(
          (inc: any) =>
            inc.project === this.DOCS_PAGES_INCLUDE.project &&
            inc.file === this.DOCS_PAGES_INCLUDE.file,
        )
      )
    ) {
      gitlabCiYaml.include = [...(gitlabCiYaml.include || []), this.DOCS_PAGES_INCLUDE];
    }

    fs.writeFileSync('./.gitlab-ci.yml', yaml.stringify(gitlabCiYaml));
  }

  private getRepoInfo() {
    const gitRemoteUrl: string = shell.exec('git remote get-url origin', { silent: true }).stdout;
    const splitRemoteUrl = gitRemoteUrl.split('/');
    const projectName = splitRemoteUrl.pop()?.split('.')[0];
    const groupName = splitRemoteUrl.pop();
    return {
      groupName,
      projectName,
      pagesUrl: `https://${groupName}.pages.tapsell.ir/${projectName}`,
    };
  }

  private mkdirDocs() {
    const dir = './docs';

    if (!fs.existsSync(dir)) {
      fs.mkdirSync(dir);
    }
    fs.writeFileSync(
      `${dir}/retype.yml`,
      `
input: .
output: ../public
branding:
  title: ${this.repoGitLabInfo?.projectName ?? 'Project Docs'}
edit: true`,
    );
  }

  private logResult() {
    const pagesUrl = this.repoGitLabInfo?.pagesUrl;

    console.log(`

    ${chalk.green('Successful! Docs are implemented')}
    -------------
    - Create ".md" files in the "docs" folder
    - Your doc will be deployed when you push to the ${chalk.blue('master')} branch.

    Docs URL: ${pagesUrl}

    - Please update the README.md file and add this URL:
          **View [Documentation](${pagesUrl})**
    `);
  }
}
