import re
import sys
from typing import Optional

KEYWORD_MAP = {
    # I/O Operations
    r"\bpaccerak\b": "print",
    r"\bpassuluak\b": "input",
    # Data Types
    r"\bbilanga\b": "int",
    r"\baksara\b": "str",
    r"\bdesimal\b": "float",
    r"\bdaptar\b": "list",
    r"\btupel\b": "tuple",
    r"\bpeta\b": "dict",
    r"\bhimpunan\b": "set",
    r"\bbolean\b": "bool",
    r"\bbytes\b": "bytes",
    r"\bbytearray\b": "bytearray",
    r"\bfrozenset\b": "frozenset",
    r"\bcomplex\b": "complex",
    # Boolean Values
    r"\bmakanja\b": "True",
    r"\bdemakanja\b": "False",
    r"\btaniaapa\b": "None",
    # Control Flow
    r"\bnakko\b": "if",
    r"\bnakkopa\b": "elif",
    r"\bnarekko\b": "else",
    r"\bulangi\b": "for",
    r"\bsedding\b": "while",
    r"\btappai\b": "break",
    r"\blaoi\b": "continue",
    r"\blewati\b": "pass",
    # Functions & Classes
    r"\bpangngaseng\b": "def",
    r"\bbaliki\b": "return",
    r"\blambda\b": "lambda",
    r"\bkelas\b": "class",
    r"\bobjek\b": "object",
    r"\binisialisasi\b": "__init__",
    r"\byield\b": "yield",
    r"\basync\b": "async",
    r"\bawait\b": "await",
    # Exception Handling
    r"\bcoba\b": "try",
    r"\bnakkosala\b": "except",
    r"\bnakkosedding\b": "finally",
    r"\bbangkitki\b": "raise",
    r"\bkudu\b": "assert",
    # Import & Module
    r"\bimpor\b": "import",
    r"\briboko\b": "from",
    r"\bsiaganga\b": "as",
    # File Operations
    r"\bsiaganga\b": "with",
    r"\bbukka\b": "open",
    r"\bmodetulis\b": '"w"',
    r"\bmodebaca\b": '"r"',
    r"\bmodeambah\b": '"a"',
    r"\bmodebiner\b": '"b"',
    r"\btulis\b": "write",
    r"\bbaca\b": "read",
    r"\bbacabarisa\b": "readline",
    r"\bbacasemua\b": "readlines",
    r"\btutup\b": "close",
    # Built-in Functions
    r"\bjangka\b": "range",
    r"\bjumlahki\b": "sum",
    r"\bcarakna\b": "len",
    r"\bpalingciddi\b": "min",
    r"\bpalinglompo\b": "max",
    r"\burutki\b": "sorted",
    r"\bbalikkidaptar\b": "reversed",
    r"\benumerate\b": "enumerate",
    r"\bzip\b": "zip",
    r"\bmap\b": "map",
    r"\bfilter\b": "filter",
    r"\ball\b": "all",
    r"\bany\b": "any",
    r"\babs\b": "abs",
    r"\bround\b": "round",
    r"\bpow\b": "pow",
    r"\btype\b": "type",
    r"\bisinstance\b": "isinstance",
    r"\bissubclass\b": "issubclass",
    r"\bcallable\b": "callable",
    r"\bhasattr\b": "hasattr",
    r"\bgetattr\b": "getattr",
    r"\bsetattr\b": "setattr",
    r"\bdelattr\b": "delattr",
    r"\bdir\b": "dir",
    r"\bvars\b": "vars",
    r"\bid\b": "id",
    r"\bhash\b": "hash",
    r"\bhelp\b": "help",
    r"\beval\b": "eval",
    r"\bexec\b": "exec",
    r"\bcompile\b": "compile",
    r"\bformat\b": "format",
    r"\brepr\b": "repr",
    r"\bascii\b": "ascii",
    r"\bchr\b": "chr",
    r"\bord\b": "ord",
    r"\bhex\b": "hex",
    r"\boct\b": "oct",
    r"\bbin\b": "bin",
    # List/Dict/Set Methods
    r"\btambai\b": "append",
    r"\bburakne\b": "pop",
    r"\burutkanki\b": "sort",
    r"\bbalikidaptar\b": "reverse",
    r"\bsisipki\b": "insert",
    r"\bhapuski\b": "remove",
    r"\bbersihki\b": "clear",
    r"\bhitungki\b": "count",
    r"\bindexki\b": "index",
    r"\bextendki\b": "extend",
    r"\bcopyaki\b": "copy",
    r"\bkeys\b": "keys",
    r"\bvalues\b": "values",
    r"\bitems\b": "items",
    r"\bget\b": "get",
    r"\bupdate\b": "update",
    r"\bsetdefault\b": "setdefault",
    r"\bpopitem\b": "popitem",
    r"\badd\b": "add",
    r"\bdiscard\b": "discard",
    r"\bunion\b": "union",
    r"\bintersection\b": "intersection",
    r"\bdifference\b": "difference",
    # String Methods
    r"\bsappai\b": "find",
    r"\bgantiki\b": "replace",
    r"\blompo\b": "upper",
    r"\bciddi\b": "lower",
    r"\bcapitalize\b": "capitalize",
    r"\btitle\b": "title",
    r"\bstrip\b": "strip",
    r"\blstrip\b": "lstrip",
    r"\brstrip\b": "rstrip",
    r"\bpecaki\b": "split",
    r"\bgabungki\b": "join",
    r"\bstartswith\b": "startswith",
    r"\bendswith\b": "endswith",
    r"\bisalpha\b": "isalpha",
    r"\bisdigit\b": "isdigit",
    r"\bisalnum\b": "isalnum",
    r"\bisspace\b": "isspace",
    r"\bislower\b": "islower",
    r"\bisupper\b": "isupper",
    r"\bzfill\b": "zfill",
    r"\bcenter\b": "center",
    r"\bljust\b": "ljust",
    r"\brjust\b": "rjust",
    # Operators & Keywords
    r"\brilaleng\b": "in",
    r"\btaniarilaleng\b": "not in",
    r"\bsisamaya\b": "is",
    r"\btaniasisamaya\b": "is not",
    r"\bdan\b": "and",
    r"\batau\b": "or",
    r"\btania\b": "not",
    r"\bglobal\b": "global",
    r"\bnonlocal\b": "nonlocal",
    r"\bdel\b": "del",
    # Context Managers
    r"\b__enter__\b": "__enter__",
    r"\b__exit__\b": "__exit__",
    # Special Methods
    r"\b__str__\b": "__str__",
    r"\b__repr__\b": "__repr__",
    r"\b__len__\b": "__len__",
    r"\b__getitem__\b": "__getitem__",
    r"\b__setitem__\b": "__setitem__",
    r"\b__delitem__\b": "__delitem__",
    r"\b__iter__\b": "__iter__",
    r"\b__next__\b": "__next__",
    r"\b__call__\b": "__call__",
    r"\b__add__\b": "__add__",
    r"\b__sub__\b": "__sub__",
    r"\b__mul__\b": "__mul__",
    r"\b__div__\b": "__div__",
    r"\b__eq__\b": "__eq__",
    r"\b__ne__\b": "__ne__",
    r"\b__lt__\b": "__lt__",
    r"\b__gt__\b": "__gt__",
    r"\b__le__\b": "__le__",
    r"\b__ge__\b": "__ge__",
}


def convert_sofinco_to_python(sofinco_code: str) -> str:
    python_code = sofinco_code
    for sofinco_keyword, python_keyword in KEYWORD_MAP.items():
        python_code = re.sub(sofinco_keyword, python_keyword, python_code)
    python_code = re.sub(r"\bsebagai\b", "as", python_code)
    python_code = re.sub(r"\t", "    ", python_code)
    return python_code


def run_sofinco_file(file_path: str, save_converted: bool = True) -> None:
    if not file_path.endswith(".sofinco"):
        raise ValueError("❌ File harus memiliki ekstensi .sofinco!")

    with open(file_path, "r", encoding="utf-8") as f:
        sofinco_code = f.read()

    python_code = convert_sofinco_to_python(sofinco_code)

    if save_converted:
        py_file_path = f"{file_path.rsplit('.', 1)[0]}.py"
        with open(py_file_path, "w", encoding="utf-8") as f:
            f.write(python_code)
        # print(f"💾 File Python hasil konversi disimpan di: {py_file_path}")

    try:
        exec(python_code, globals())
    except SyntaxError as e:
        raise Exception(
            f"❌ Error sintaks di baris {e.lineno}: {e.text.strip() if e.text else 'N/A'}"
        ) from e
    except Exception as e:
        raise Exception(f"❌ Error eksekusi: {str(e)}") from e


def main():
    import argparse

    parser = argparse.ArgumentParser(
        description="Sofinco - Bahasa Pemrograman Bahasa Bugis-Makassar Berbasis Python",
        usage="sofinco <namafile.sofinco> [--nosv]",
        epilog="Contoh: sofinco program_saya.sofinco",
    )
    parser.add_argument("file", help="Path ke file program Sofinco (ekstensi .sofinco)")
    parser.add_argument(
        "--nosv",
        action="store_false",
        dest="save_converted",
        help="Jangan menyimpan file Python hasil konversi",
    )
    args = parser.parse_args()

    try:
        run_sofinco_file(args.file, args.save_converted)
        # print("\n✅ Program Sofinco berjalan dengan sukses!")
    except Exception as e:
        print(f"\n{str(e)}", file=sys.stderr)
        sys.exit(1)


if __name__ == "__main__":
    main()
