import os, site, json, datetime, random, sys, time

_CONFIG   = os.path.join(os.path.expanduser("~"), ".hazimpp_config.json")
_STATS    = os.path.join(os.path.expanduser("~"), ".hazimpp_stats.json")
_PTH_FILE = "hazimpp_autorun.pth"
_PTH_DATA = "import hazimpp\n"

R    = "\033[0m"
BOLD = "\033[1m"
DIM  = "\033[2m"

_THEMES = {
    "1": ("🌙 ليلي",     "\033[1;35m", "\033[35m",  "◈"),
    "2": ("☀️  شمسي",    "\033[1;33m", "\033[33m",  "★"),
    "3": ("🌊 محيط",     "\033[1;96m", "\033[36m",  "◆"),
    "4": ("🌹 وردي",     "\033[38;5;213m\033[1m", "\033[38;5;205m", "♥"),
    "5": ("🌿 غابة",     "\033[1;32m", "\033[32m",  "◉"),
    "6": ("⚡ نيون",      "\033[1;92m", "\033[92m",  "▸"),
    "7": ("🔥 نار",       "\033[1;31m", "\033[33m",  "▲"),
    "8": ("❄️  جليد",    "\033[1;97m", "\033[36m",  "❅"),
    "9": ("🌈 قوس قزح",  "RAINBOW",    "\033[93m",  "◐"),
}

_DAYS = {0:"الاثنين",1:"الثلاثاء",2:"الأربعاء",3:"الخميس",4:"الجمعة",5:"السبت",6:"الأحد"}
_MONTHS = {1:"يناير",2:"فبراير",3:"مارس",4:"أبريل",5:"مايو",6:"يونيو",
           7:"يوليو",8:"أغسطس",9:"سبتمبر",10:"أكتوبر",11:"نوفمبر",12:"ديسمبر"}

_QUOTES = [
    "أنت أقوى مما تظن وأذكى مما تعتقد.",
    "كل خطأ في الكود يعلّمك شيئاً جديداً.",
    "البداية دائماً الخطوة الأصعب، لكنها الأهم.",
    "العظمة لا تأتي بالصدفة، بل بالمثابرة.",
    "المبرمج الحقيقي لا يستسلم أمام الأخطاء.",
    "من لا يجرب لا يتعلم، ومن لا يتعلم لا يتقدم.",
    "الوقت لا يعود، استثمره فيما يستحق.",
    "اجعل كل كود تكتبه أفضل من السابق.",
    "حلّ مشكلة واحدة يومياً يصنع خبيراً في سنة.",
    "الصبر والتعلم المستمر سر كل مبرمج ناجح.",
]

_TIPS = [
    "💡 نصيحة: استخدم list comprehension بدلاً من for عندما تستطيع.",
    "💡 نصيحة: f-strings أسرع وأوضح من .format() و %.",
    "💡 نصيحة: استخدم enumerate() بدلاً من range(len(list)).",
    "💡 نصيحة: zip() تجمع قائمتين في حلقة واحدة بسهولة.",
    "💡 نصيحة: collections.Counter لعدّ العناصر بسرعة.",
    "💡 نصيحة: with open() يغلق الملف تلقائياً بأمان.",
    "💡 نصيحة: defaultdict تتجنب خطأ KeyError.",
    "💡 نصيحة: dataclasses توفّر عليك كتابة __init__ يدوياً.",
    "💡 نصيحة: استخدم _ للمتغيرات التي لا تحتاجها في الحلقة.",
    "💡 نصيحة: any() و all() أسرع من حلقات الفحص اليدوية.",
]

_ACHIEVEMENTS = [
    (1,    "أول خطوة في المشوار 🌱"),
    (10,   "مبتدئ متحمس 📚"),
    (50,   "مبرمج نشيط ⚡"),
    (100,  "مبرمج محترف 🎯"),
    (500,  "خبير لا يتوقف 🚀"),
    (1000, "أسطورة البرمجة 👑"),
]

_STREAK_ACHIEVEMENTS = [
    (3,  "3 أيام متتالية 🔥"),
    (7,  "أسبوع كامل من الإخلاص 🌟"),
    (14, "أسبوعان متواصلان 💪"),
    (30, "شهر من المثابرة 🏅"),
    (100,"مئة يوم متتالي! 🏆"),
]

_RAINBOW = ["\033[1;31m","\033[1;33m","\033[1;32m","\033[1;36m","\033[1;34m","\033[1;35m"]


def _rainbow(text):
    out = ""
    ci = 0
    for ch in text:
        if ch != " ":
            out += _RAINBOW[ci % len(_RAINBOW)] + ch
            ci += 1
        else:
            out += " "
    return out + R


def _greeting():
    h = datetime.datetime.now().hour
    if   5  <= h < 12: return "صباح الخير"
    elif 12 <= h < 17: return "مساء الخير"
    elif 17 <= h < 21: return "مساء النور"
    else:              return "مرحباً بك"


def _arabic_date():
    n = datetime.datetime.now()
    return f"{_DAYS[n.weekday()]}  {n.day} {_MONTHS[n.month]} {n.year}  |  {n.strftime('%H:%M')}"


def _load(path):
    try:
        if os.path.exists(path):
            with open(path, "r", encoding="utf-8") as f:
                return json.load(f)
    except Exception:
        pass
    return {}


def _save(path, data):
    try:
        with open(path, "w", encoding="utf-8") as f:
            json.dump(data, f, ensure_ascii=False, indent=2)
    except Exception:
        pass


def _update_stats():
    stats  = _load(_STATS)
    today  = datetime.date.today().isoformat()
    last   = stats.get("last_date", "")
    streak = stats.get("streak", 0)
    yest   = (datetime.date.today() - datetime.timedelta(days=1)).isoformat()

    if last == today:
        pass
    elif last == yest:
        streak += 1
    else:
        streak = 1

    stats["total"]       = stats.get("total", 0) + 1
    stats["streak"]      = streak
    stats["best_streak"] = max(stats.get("best_streak", 0), streak)
    stats["last_date"]   = today
    if "first_date" not in stats:
        stats["first_date"] = today

    _save(_STATS, stats)
    return stats


def _check_new_achievement(stats):
    total  = stats.get("total", 0)
    streak = stats.get("streak", 0)
    done   = set(stats.get("unlocked", []))

    for needed, name in _ACHIEVEMENTS:
        if total >= needed and name not in done:
            done.add(name)
            stats.setdefault("unlocked", []).append(name)
            _save(_STATS, stats)
            return f"🏆 إنجاز جديد: {name}"

    for needed, name in _STREAK_ACHIEVEMENTS:
        if streak >= needed and name not in done:
            done.add(name)
            stats.setdefault("unlocked", []).append(name)
            _save(_STATS, stats)
            return f"🔥 إنجاز سلسلة: {name}"

    return None


def _install_pth():
    dirs = []
    try:    dirs += site.getsitepackages()
    except: pass
    try:    dirs.append(site.getusersitepackages())
    except: pass
    for d in dirs:
        p = os.path.join(d, _PTH_FILE)
        if os.path.exists(p):
            return
        try:
            os.makedirs(d, exist_ok=True)
            open(p, "w").write(_PTH_DATA)
            return
        except Exception:
            continue


def _tprint(text, delay=0.018):
    for ch in text:
        sys.stdout.write(ch)
        sys.stdout.flush()
        time.sleep(delay)
    sys.stdout.write("\n")
    sys.stdout.flush()


def _line(char, color, width=50):
    return color + (char * width)[:width] + R


def _display(cfg, stats):
    theme_key = cfg.get("theme", "3")
    theme     = _THEMES.get(theme_key, _THEMES["3"])
    _, primary, secondary, icon = theme

    name      = cfg.get("name", "")
    tagline   = cfg.get("tagline", "")
    animate   = cfg.get("animate", False)
    show_tip  = cfg.get("show_tip", True)
    show_time = cfg.get("show_time", True)
    show_stat = cfg.get("show_stats", True)

    total  = stats.get("total", 1)
    streak = stats.get("streak", 1)
    achievement = _check_new_achievement(stats)

    width = 50
    border_char = "═"
    top    = primary + "╔" + border_char * width + "╗" + R
    bottom = primary + "╚" + border_char * width + "╝" + R
    empty  = primary + "║" + " " * width + "║" + R

    def row(text):
        return primary + "║" + R + "  " + text

    greeting_line = f"{secondary}{_greeting()}{R}، {primary}{BOLD}"
    if primary == "RAINBOW":
        name_colored = _rainbow(name)
        greeting_line = f"{secondary}{_greeting()}{R}، {name_colored}"
    else:
        name_colored = primary + BOLD + name + R
        greeting_line = f"{secondary}{_greeting()}{R}، {name_colored}"

    lines = [top, empty]

    # Greeting + name
    gl = f"  ✨  {greeting_line}  ✨"
    if animate:
        sys.stdout.write(primary + "║" + R)
        _tprint(f"  ✨  {_greeting()}، {name}  ✨", delay=0.025)
    else:
        lines.append(row(f"✨  {greeting_line}  ✨"))

    # Tagline
    if tagline:
        lines.append(row(f"{DIM}『 {tagline} 』{R}"))

    lines.append(empty)

    # Date & time
    if show_time:
        lines.append(row(f"🕐  {secondary}{_arabic_date()}{R}"))

    # Stats
    if show_stat:
        best = stats.get("best_streak", streak)
        lines.append(row(f"💻  {secondary}جلسة #{total}{R}  •  🔥 سلسلة {streak} يوم  •  🏅 أفضل {best}"))

    # Achievement
    if achievement:
        lines.append(row(f"{BOLD}{achievement}{R}"))

    lines.append(empty)

    # Quote or tip (alternate)
    if show_tip:
        if total % 2 == 0:
            content = f'"{random.choice(_QUOTES)}"'
        else:
            content = random.choice(_TIPS)
        lines.append(row(f"{secondary}{content}{R}"))
        lines.append(empty)

    lines.append(bottom)

    if not animate:
        print("\n".join(lines))
    else:
        for l in lines:
            print(l)

    print()


def setup():
    print("\n" + BOLD + "╔" + "═"*46 + "╗" + R)
    print(BOLD + "║" + R + "      🎨  إعداد مكتبة hazimpp  🎨      " + BOLD + "║" + R)
    print(BOLD + "╚" + "═"*46 + "╝\n" + R)

    name = input("  👤  اكتب اسمك: ").strip()

    tagline = input("  ✍️   شعارك الشخصي (اضغط Enter للتخطي): ").strip()

    print("\n  🎨  اختر ثيم الألوان:\n")
    for k, (tname, pri, sec, ic) in _THEMES.items():
        color = _RAINBOW[int(k) % len(_RAINBOW)] if pri == "RAINBOW" else pri
        print(f"     {color}[{k}]{R}  {ic}  {tname}")

    theme = input("\n  رقم الثيم (1-9): ").strip()
    if theme not in _THEMES:
        theme = "3"

    print("\n  ⚙️   خيارات العرض:\n")
    animate   = _ask("  هل تريد تأثير الكتابة التدريجي؟")
    show_time = _ask("  هل تريد عرض التاريخ والوقت؟")
    show_stat = _ask("  هل تريد عرض إحصائيات الجلسات؟")
    show_tip  = _ask("  هل تريد اقتباساً أو نصيحة يومية؟")

    cfg = {
        "name": name, "tagline": tagline, "theme": theme,
        "animate": animate, "show_time": show_time,
        "show_stats": show_stat, "show_tip": show_tip,
    }
    _save(_CONFIG, cfg)
    _install_pth()

    stats = _update_stats()

    print("\n" + BOLD + "  ✅  تم الحفظ! هكذا سيظهر اسمك:\n" + R)
    _display(cfg, stats)
    print("  شغّل «hazimpp-setup» في أي وقت لتغيير الإعدادات.\n")


def _ask(q):
    return input(f"{q} (y/n): ").strip().lower() != "n"


def _run():
    cfg = _load(_CONFIG)
    if not cfg or not cfg.get("name"):
        return
    stats = _update_stats()
    _display(cfg, stats)


_run()
