import json
import os
import sys
from pathlib import Path
from typing import List, Optional

import click

from .bridge import BridgeUsername
from .error import SlackException
from .github import api as github_api
from .slack import api as slack_api


def get_bridge_usernames(file_username: Optional[str]) -> List[BridgeUsername]:
    if file_username is None:
        return []
    return list(
        map(
            lambda item: BridgeUsername(**item),
            json.loads(Path(file_username).read_text()),
        )
    )


@click.command(
    help="""GitHub repository's pull requests slack notifier\n
Required environments variables\n
    - GITHUB_TOKEN: Your GitHub Personal Access Token.\n
    - SLACK_URL: Your Slack webhook url."""
)
@click.option(
    "--repo",
    "-r",
    type=str,
    help="GitHub repository name (owner/repo).",
    required=True,
)
@click.option(
    "--file-username",
    "-u",
    type=str,
    help="Corresponding files for GitHub and Slack usernames. (see. example in README.md)",
)
@click.option(
    "--limit",
    "-l",
    type=int,
    default=20,
    help="Number of Pull Requests to notify Slack.",
    required=True,
)
@click.option(
    "--icon",
    "-i",
    is_flag=True,
    type=bool,
    default=False,
    help="Give GitHub icons to Slack notifications.",
    required=False,
)
def main(repo: str, file_username: Optional[str], limit: int, icon: bool) -> None:
    if limit > 20:
        raise ValueError("Cannot set more than 20 items.")

    gh = github_api.Client(token=os.environ["GITHUB_TOKEN"])
    # get pull requests
    pulls = gh.get_pulls(repo=repo, limit=limit)
    # get total pull requests count
    total_pulls = gh.get_total_pulls(repo=repo)
    # get GitHub and GitHub bridge username
    usernames = get_bridge_usernames(file_username=file_username)

    # send slack
    sl = slack_api.Client(usernames=usernames, icon=icon)
    try:
        sl.post(repo=repo, pulls=pulls, total_pulls=total_pulls)
    except SlackException as e:
        print(f"Slack Exception {e.response['detail']}", end=" ")
        sys.exit(1)


if __name__ == "__main__":
    main()
