from Api import Crunchium
import os
import sys
import argparse


class CrunchiumDownloader:
    def __init__(self, url: str, season: int = None, episode: int = None):
        self.url = url
        self.season = season
        self.episode = episode
        self.cr = Crunchium()

    def run(self):
        if not self.cr.get_item("access_token"):
            self.cr.get_access_token()

        media_id = self.cr.extract_type_and_id(self.url)
        info = self.cr.get_media_info(media_id)

        if not info:
            self.cr.error("Failed to retrieve media information.")
            sys.exit(1)

        if not self.cr.get_item("download_dir"):
            self.cr.error("No download directory set.")
            sys.exit(1)

        self.cr.debug(f"Title: {info.get('title')}")
        self.cr.debug(f"Type: {info.get('type')}")

        try:
            media_type = info.get("type")
            if media_type == "series":
                self.handle_series(info)
            elif media_type == "movie":
                self.cr.download_movie(info)
            else:
                raise AttributeError("Unknown media type")
        except AttributeError:
            self.cr.error(f"Unsupported media type: {info.get('type')}")

    def handle_series(self, info: dict):
        seasons = self.cr.get_seasons(info)
        if not seasons:
            self.cr.error("Failed to retrieve seasons.")
            return

        if self.season is None:
            self.cr.critical("No season number provided. Downloading all seasons.")
            if self.episode:
                self.cr.critical("Episode number provided but season not selected. Downloading all episodes.")

            for season in seasons:
                self.download_season(season)
        else:
            selected_season = next((s for s in seasons if s["season_number"] == self.season), None)
            if not selected_season:
                self.cr.error(f"Season {self.season} not found.")
                return

            self.download_season(selected_season)

    def download_season(self, season: dict):
        self.cr.info(f"Selecting season: {season.get('season_number')}")
        episodes = self.cr.get_episodes(season.get("id"))

        if not episodes:
            self.cr.error("Failed to retrieve episodes.")
            return

        if self.episode is None:
            self.cr.critical("No episode number provided. Downloading all episodes.")
            for ep in episodes:
                self.clear_console()
                self.cr.download_episode(ep)
        else:
            selected_episode = next((e for e in episodes if e["episode_number"] == self.episode), None)
            if not selected_episode:
                self.cr.error(f"Episode {self.episode} not found in season {season.get('season_number')}.")
                return
            self.clear_console()
            self.cr.download_episode(selected_episode)

    def clear_console(self):
        os.system("cls" if os.name == "nt" else "clear")


if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="Crunchium downloader")
    parser.add_argument("-u", "--url", type=str, required=True, help="Crunchyroll media URL")
    parser.add_argument("-s", "--season", type=int, help="Season number (optional)")
    parser.add_argument("-e", "--episode", type=int, help="Episode number (optional)")
    args = parser.parse_args()

    try:
        CrunchiumDownloader(args.url, args.season, args.episode).run()
    except Exception as ex:
        print(f"Error: {ex}")
