import traceback


def handle_exception(exc, file, mode, theme, logger):
    exc_type = type(exc).__name__
    exc_msg = str(exc)

    tb = traceback.extract_tb(exc.__traceback__)
    if tb:
        last = tb[-1]
        line_no = last.lineno
        code_line = last.line
    else:
        line_no = None
        code_line = None

    # log
    logger.log(exc_type, exc_msg, file, line_no, code_line, traceback.format_exc())

    # minimal
    if mode == "minimal":
        print(theme.error_line(f"⚠️ {exc_type}: {exc_msg}"))
        print(theme.footer("Program stopped."))
        return

    # standard + verbose
    print(theme.header("vox"))
    print(theme.error_block("❌ vox says something went wrong."))

    print(theme.section("🧠 What happened:"))
    if exc_type == "NameError":
        print(theme.body("You used a name that Python does not recognize."))
    elif exc_type == "TypeError":
        print(theme.body("You used a value in an invalid way."))
    elif exc_type == "IndexError":
        print(theme.body("You accessed a list index that does not exist."))
    elif exc_type == "KeyError":
        print(theme.body("You accessed a dictionary key that does not exist."))
    elif exc_type == "AttributeError":
        print(theme.body("You tried to use an attribute that does not exist."))
    else:
        print(theme.body(exc_msg or "Unknown error."))

    if line_no and code_line:
        print(theme.location(file, line_no, code_line))

    if mode == "verbose":
        print(theme.section("\n🧠 Full traceback:"))
        print(theme.body(traceback.format_exc()))

    print(theme.footer("\n🛑 Program stopped."))
