from typing import List
from models.vulnerability_intelligence import VulnerabilityIntelligence
from terminal.colors import BOLD, GREEN, YELLOW, RED, BLACK_ON_WHITE, RESET

class VulnerabilityIntelligencePrinter:
    @staticmethod
    def print(vulnerability_intelligence: List[VulnerabilityIntelligence]) -> None:
        for vuln_intelligence in vulnerability_intelligence:
            print(f"\n{BOLD}{vuln_intelligence.id}{RESET}")
            print(f"{'-' * 40}")
            
            print(f"{GREEN}Date:{RESET}")
            for date in vuln_intelligence.dates:
                print(f"  {BOLD}{date['source']}{RESET}: {date['date']}")
            print()
            
            print(f"{GREEN}URL:{RESET}")
            for url in vuln_intelligence.urls:
                print(f"  ({BOLD}{url['date']} / {url['source']}{RESET}): {url['url']}")
            print()
            
            print(f"{GREEN}Title:{RESET}")
            for title in vuln_intelligence.titles:
                print(f"  ({BOLD}{title['date']} / {title['source']}{RESET}): {title['text']}")
            print()
            
            print(f"{GREEN}Description:{RESET}")
            for desc in vuln_intelligence.descriptions:
                print(f"  ({BOLD}{desc['date']} / {desc['source']}{RESET}): {desc['text']}")
            print()

            if vuln_intelligence.reference_urls:
                reference_urls = [*vuln_intelligence.reference_urls]
                reference_urls.sort()
                print(f"{GREEN}Reference URLs:{RESET}")
                for url in reference_urls:
                    print(f"  - {url}")
                print()

            if vuln_intelligence.base_scores:
                print(f"{GREEN}Base Score:{RESET}")
                for score in vuln_intelligence.base_scores:
                    color_score = VulnerabilityIntelligencePrinter._colorize_score(score["score"])
                    print(f"  ({BOLD}{score['date']} / {score['source']}{RESET}): {color_score}")
                print()

            if vuln_intelligence.severities:
                print(f"{GREEN}Severity:{RESET}")
                for severity in vuln_intelligence.severities:
                    color_severity = VulnerabilityIntelligencePrinter._colorize_severity(severity["severity"])
                    print(f"  ({BOLD}{severity['date']} / {severity['source']}{RESET}): {color_severity}")
                print()

            if vuln_intelligence.vulnerable_components:
                print(f"{GREEN}Vulnerable Components:{RESET}")
                for component in vuln_intelligence.vulnerable_components:
                    print(f"  - {component}")
                print()

            if vuln_intelligence.tags:
                print(f"{GREEN}Tags:{RESET} {', '.join(vuln_intelligence.tags)}")
                print()

            if vuln_intelligence.weaknesses:
                print(f"{GREEN}Weaknesses:{RESET} {', '.join(vuln_intelligence.weaknesses)}")
                print()

    @staticmethod
    def _colorize_score(score: str) -> str:
        try:
            score_value = float(score.capitalize())
            if 5 <= score_value < 7:
                return f"{YELLOW}{score.capitalize()}{RESET}"
            if 7 <= score_value <= 9:
                return f"{RED}{score.capitalize()}{RESET}"
            elif score_value > 9:
                return f"{BLACK_ON_WHITE}{score.capitalize()}{RESET}"
            else:
                return score.capitalize()
        except (ValueError, TypeError):
            return score.capitalize()

    @staticmethod
    def _colorize_severity(severity: str) -> str:
        severity = severity.lower()
        if severity == "low":
            return f"{GREEN}{severity.capitalize()}{RESET}"
        elif severity in ["moderate", "medium"]:
            return f"{YELLOW}{severity.capitalize()}{RESET}"
        elif severity == "high":
            return f"{RED}{severity.capitalize()}{RESET}"
        elif severity == "critical":
            return f"{BLACK_ON_WHITE}{severity.capitalize()}{RESET}"
        else:
            return severity.capitalize()
