import json
from pathlib import Path

from colorama import Fore

from common import (
    ExitCode,
    end_collapsible_section,
    exec_command,
    exit_message,
    get_env_variable,
    get_env_variable_required,
    print_message,
    set_env_variable,
    start_collapsible_section,
)
from common.sonar_helper import SonarHelper, SonarScannerType
from src.interface.project import ProjectInterface


class FlutterProjectInterface(ProjectInterface):
    def __init__(self):
        super().__init__()
        self.no_pub_supress = "--no-pub --suppress-analytics"
        sci_debug = get_env_variable("SCI_FLUTTER_BUILD_DEBUG")
        self.build_kind = "debug" if sci_debug else "release"

    def _install(self):

        fvmrc = Path(".fvmrc")
        ci_project_dir = get_env_variable_required("CI_PROJECT_DIR")
        set_env_variable("PUB_CACHE", f"{ci_project_dir}/.pub")
        if fvmrc.is_file():
            fvm_section = start_collapsible_section(
                "Instalando FVM e Flutter.",
            )
            exec_command("fvm use --skip-pub-get")
            end_collapsible_section(fvm_section)

            dep_section = start_collapsible_section(
                "Instalando Dependências.",
            )
            self._exec_flutter_command("pub get")
            end_collapsible_section(dep_section)

        else:
            exit_message("Arquivo de configuração do FVM não encontrado.")

    def validate(self):
        super().validate()
        if self.buildable_project.skip_build():
            return

        self._install()
        self._exec_flutter_analyze()

    def compile(self):
        if self.buildable_project.skip_build():
            return

        self._install()

    def _build_app_base(self):
        ci_job_id = get_env_variable_required("CI_JOB_ID")

        build_type = "apk"

        if get_env_variable("CI_COMMIT_TAG"):
            build_type = "appbundle"

        return f"build {build_type} --{self.build_kind} --build-number={ci_job_id} --target-platform android-arm64"

    def unit_test(self):
        if self.buildable_project.skip_build():
            return

        self._install()
        self._exec_flutter_command("pub add full_coverage")
        self._exec_flutter_command("pub run full_coverage")
        self._exec_flutter_command(
            f"test --reporter=expanded --coverage {self.no_pub_supress}"
        )

    def sonar_scanner(self):
        sonar_helper = SonarHelper(sonar_scanner_type=SonarScannerType.FLUTTER)
        sonar_helper.scanner_analyze()

    def _exec_flutter_analyze(self):
        print(" ")
        print_message(
            "Iniciando a execução da análise estática",
            Fore.YELLOW,
        )
        print(" ")

        self._exec_flutter_command(
            "analyze --current-package --congratulate --preamble --no-fatal-infos "
            f"--no-fatal-warnings {self.no_pub_supress} --write=analyzer-output.txt"
        )

        print(" ")
        print_message(
            "Análise estática finalizada com sucesso.",
            Fore.GREEN,
        )

    @staticmethod
    def _exec_flutter_command(command):

        command_result_flutter = exec_command(f"fvm flutter {command}")

        if command_result_flutter.exit_code == ExitCode.ERROR:
            exit_message("Flutter command failed. Exiting...")

    def _send_to_firebase(self, environment, apk_file_name):
        ci_commit_tag = get_env_variable("CI_COMMIT_TAG")

        if not ci_commit_tag:
            ci_commit_message = get_env_variable_required("CI_COMMIT_MESSAGE")
            ci_project_url = get_env_variable_required("CI_PROJECT_URL")
            ci_commit_sha = get_env_variable_required("CI_COMMIT_SHA")
            ci_commit_ref_name = get_env_variable_required("CI_COMMIT_REF_NAME")
            sci_firebase_app_ids = json.loads(
                get_env_variable_required("SCI_FIREBASE_ANDROID_APP_IDS")
            )
            sci_distribution_groups = get_env_variable_required(
                "SCI_FIREBASE_DISTRIBUTION_GROUPS"
            )

            firebase_app_id = sci_firebase_app_ids[environment]

            release_notes_message = (
                f"Commit Message: {ci_commit_message}\n\n"
                f"Branch: {ci_commit_ref_name}\n\n"
                f"Commit: {ci_project_url}/-/commit/{ci_commit_sha}\n\n"
            )

            firebase_command = (
                f"firebase appdistribution:distribute build/app/outputs/flutter-apk/{apk_file_name}.apk "
                f"--app {firebase_app_id} "
                f"--release-notes '{release_notes_message}' "
                f'--groups "{sci_distribution_groups}"'
            )

            exec_command(firebase_command)

        else:
            print_message("Package para tags ainda em processo de implementação")
