import os
import sys
import ctypes
import urllib.request
import zipfile
import shutil
import threading
import tkinter as tk
from tkinter import ttk, messagebox

# --- GEREKLİ YOLLAR VE LİNKLER ---
DOCUMENTS_DIR = os.path.join(os.environ['USERPROFILE'], 'Documents')
DESKTOP_DIR = os.path.join(os.environ['USERPROFILE'], 'Desktop')
START_MENU_DIR = os.path.join(os.environ['APPDATA'], 'Microsoft', 'Windows', 'Start Menu', 'Programs')

GOLDER_DOC_URL = "https://golder.biz/Golder.zip"
GOLDER_C_URL = "https://golder.biz/Program.zip"

TARGET_DOC_DIR = os.path.join(DOCUMENTS_DIR, "Golder")
TARGET_C_DIR = "C:\\Golder"
SHORTCUT_TARGET = "C:\\Golder\\main.exe"

DESKTOP_SHORTCUT = os.path.join(DESKTOP_DIR, "Golder.lnk")
START_MENU_SHORTCUT = os.path.join(START_MENU_DIR, "Golder.lnk")

REQUIRED_DISK_SPACE_MB = 500 # Gerekli tahmini boş alan (MB)

# --- YÖNETİCİ İZNİ KONTROLÜ ---
def is_admin():
    try:
        return ctypes.windll.shell32.IsUserAnAdmin()
    except:
        return False

if not is_admin():
    ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, " ".join(sys.argv), None, 1)
    sys.exit()

# --- YARDIMCI FONKSİYONLAR ---
def get_free_space_mb(dirname):
    free_bytes = ctypes.c_ulonglong(0)
    ctypes.windll.kernel32.GetDiskFreeSpaceExW(ctypes.c_wchar_p(dirname), None, None, ctypes.pointer(free_bytes))
    return free_bytes.value / (1024 * 1024)

def create_shortcut(target, shortcut_path):
    vbs_script = f"""
Set ws = CreateObject("WScript.Shell")
Set shortcut = ws.CreateShortcut("{shortcut_path}")
shortcut.TargetPath = "{target}"
shortcut.WorkingDirectory = "{os.path.dirname(target)}"
shortcut.Save
    """
    vbs_path = os.path.join(os.environ['TEMP'], "create_shortcut.vbs")
    with open(vbs_path, "w", encoding="utf-8") as f:
        f.write(vbs_script)
    os.system(f'cscript //nologo "{vbs_path}"')
    os.remove(vbs_path)

# --- GUI (ARAYÜZ) SINIFI ---
class InstallerApp(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("Golder Kurulum Sihirbazı")
        self.geometry("500x350")
        self.resizable(False, False)
        
        self.frames = {}
        self.current_frame = None

        # Sayfaları oluştur
        self.create_welcome_page()
        self.create_maintenance_page()
        self.create_check_page()
        self.create_action_page()
        self.create_finish_page()
        self.create_uninstall_finish_page()

        # Kurulum durumunu kontrol et
        if self.is_installed():
            self.show_frame("maintenance")
        else:
            self.show_frame("welcome")

    def is_installed(self):
        # Programın herhangi bir bileşeni yüklü mü kontrolü
        return os.path.exists(TARGET_C_DIR) or os.path.exists(TARGET_DOC_DIR)

    def show_frame(self, name):
        if self.current_frame:
            self.current_frame.pack_forget()
        self.current_frame = self.frames[name]
        self.current_frame.pack(fill="both", expand=True)

    # --- SAYFA OLUŞTURMA FONKSİYONLARI ---

    def create_welcome_page(self):
        frame = tk.Frame(self)
        self.frames["welcome"] = frame
        
        tk.Label(frame, text="Golder Kurulumuna Hoş Geldiniz", font=("Arial", 16, "bold")).pack(pady=30)
        tk.Label(frame, text="Bu sihirbaz Golder yazılımını bilgisayarınıza kuracaktır.\n\nDevam etmek için 'İleri' butonuna tıklayın.", justify="center").pack(pady=20)
        
        btn_frame = tk.Frame(frame)
        btn_frame.pack(side="bottom", fill="x", pady=10, padx=20)
        tk.Button(btn_frame, text="İptal", width=10, command=self.destroy).pack(side="left")
        tk.Button(btn_frame, text="İleri >", width=10, command=lambda: self.show_frame("check")).pack(side="right")

    def create_maintenance_page(self):
        frame = tk.Frame(self)
        self.frames["maintenance"] = frame
        
        tk.Label(frame, text="Golder Zaten Kurulu", font=("Arial", 16, "bold"), fg="blue").pack(pady=20)
        tk.Label(frame, text="Sisteminizde Golder'ın kurulu olduğu tespit edildi.\nLütfen yapmak istediğiniz işlemi seçin.", justify="center").pack(pady=10)
        
        btn_frame = tk.Frame(frame)
        btn_frame.pack(pady=10)

        tk.Button(btn_frame, text="Güncelle (Kaldır ve Yeniden Kur)", width=30, height=2, command=self.start_update).pack(pady=10)
        tk.Button(btn_frame, text="Tamamen Kaldır", width=30, height=2, command=self.start_uninstall).pack(pady=10)
        
        bottom_frame = tk.Frame(frame)
        bottom_frame.pack(side="bottom", fill="x", pady=10, padx=20)
        tk.Button(bottom_frame, text="Çıkış", width=10, command=self.destroy).pack(side="right")

    def create_check_page(self):
        frame = tk.Frame(self)
        self.frames["check"] = frame
        
        tk.Label(frame, text="Güvenlik ve Sistem Kontrolü", font=("Arial", 14, "bold")).pack(pady=20)
        
        self.check_status = tk.StringVar(value="Sisteminiz kontrol ediliyor...")
        tk.Label(frame, textvariable=self.check_status, justify="left").pack(pady=10)
        
        btn_frame = tk.Frame(frame)
        btn_frame.pack(side="bottom", fill="x", pady=10, padx=20)
        tk.Button(btn_frame, text="< Geri", width=10, command=lambda: self.show_frame("welcome")).pack(side="left")
        
        self.install_btn = tk.Button(btn_frame, text="Kur >", width=10, state="disabled", command=self.start_installation)
        self.install_btn.pack(side="right")

        frame.bind("<Visibility>", lambda e: self.run_checks())

    def create_action_page(self):
        # Bu sayfa hem kurma, hem kaldırma hem de güncelleme işlemi için ortak kullanılacak
        frame = tk.Frame(self)
        self.frames["action"] = frame
        
        self.action_title = tk.Label(frame, text="İşlem Yapılıyor...", font=("Arial", 14, "bold"))
        self.action_title.pack(pady=20)
        
        self.status_label = tk.Label(frame, text="Lütfen bekleyin...")
        self.status_label.pack(pady=10)

        self.progress = ttk.Progressbar(frame, orient="horizontal", length=400, mode="determinate")
        self.progress.pack(pady=20)

    def create_finish_page(self):
        frame = tk.Frame(self)
        self.frames["finish"] = frame
        
        tk.Label(frame, text="Kurulum Tamamlandı!", font=("Arial", 16, "bold")).pack(pady=30)
        tk.Label(frame, text="Golder bilgisayarınıza başarıyla kuruldu.\nMasaüstü ve Başlat menüsünden kısayollara erişebilirsiniz.", justify="center").pack(pady=20)
        
        btn_frame = tk.Frame(frame)
        btn_frame.pack(side="bottom", fill="x", pady=10, padx=20)
        tk.Button(btn_frame, text="Bitir", width=10, command=self.destroy).pack(side="right")

    def create_uninstall_finish_page(self):
        frame = tk.Frame(self)
        self.frames["uninstall_finish"] = frame
        
        tk.Label(frame, text="Kaldırma Tamamlandı", font=("Arial", 16, "bold")).pack(pady=30)
        tk.Label(frame, text="Golder ve tüm ilişkili dosyaları\nsisteminizden başarıyla kaldırıldı.", justify="center").pack(pady=20)
        
        btn_frame = tk.Frame(frame)
        btn_frame.pack(side="bottom", fill="x", pady=10, padx=20)
        tk.Button(btn_frame, text="Kapat", width=10, command=self.destroy).pack(side="right")

    # --- İŞLEM FONKSİYONLARI ---

    def run_checks(self):
        msg = ""
        ready = True

        free_space = get_free_space_mb("C:\\")
        if free_space < REQUIRED_DISK_SPACE_MB:
            msg += f"❌ Yetersiz disk alanı. (Gereken: {REQUIRED_DISK_SPACE_MB}MB, Mevcut: {int(free_space)}MB)\n"
            ready = False
        else:
            msg += f"✅ C: Diskinde yeterli alan var. ({int(free_space)} MB boş)\n"

        if self.is_installed():
            msg += "\n⚠️ Uyarı: Golder klasörleri sistemde zaten mevcut.\nKuruluma devam ederseniz eski dosyalarınızın üzerine yazılacaktır.\n"
        else:
            msg += "\n✅ Golder klasörleri için konumlar temiz.\n"

        self.check_status.set(msg)
        if ready:
            self.install_btn.config(state="normal")

    def update_progress(self, block_num, block_size, total_size):
        if total_size > 0:
            downloaded = block_num * block_size
            percent = (downloaded / total_size) * 100
            self.progress["value"] = percent
            self.update_idletasks()

    def perform_uninstall(self):
        # Mevcut dosyaları ve kısayolları temizleme fonksiyonu (Arka plan işlemi)
        self.status_label.config(text="Eski dosyalar ve kısayollar temizleniyor...")
        self.update_idletasks()
        
        if os.path.exists(TARGET_DOC_DIR):
            shutil.rmtree(TARGET_DOC_DIR, ignore_errors=True)
        if os.path.exists(TARGET_C_DIR):
            shutil.rmtree(TARGET_C_DIR, ignore_errors=True)
        if os.path.exists(DESKTOP_SHORTCUT):
            os.remove(DESKTOP_SHORTCUT)
        if os.path.exists(START_MENU_SHORTCUT):
            os.remove(START_MENU_SHORTCUT)

    def extract_and_move(self, zip_path, target_dir):
        temp_extract_dir = zip_path + "_extracted"
        with zipfile.ZipFile(zip_path, 'r') as zip_ref:
            zip_ref.extractall(temp_extract_dir)
        
        extracted_golder = os.path.join(temp_extract_dir, "Golder")
        if not os.path.exists(extracted_golder):
            extracted_golder = temp_extract_dir

        if os.path.exists(target_dir):
            shutil.rmtree(target_dir)
            
        shutil.move(extracted_golder, target_dir)
        if os.path.exists(temp_extract_dir):
            shutil.rmtree(temp_extract_dir, ignore_errors=True)

    # --- THREAD (İŞ PARÇACIĞI) BAŞLATICILAR ---

    def start_uninstall(self):
        self.show_frame("action")
        self.action_title.config(text="Kaldırılıyor...")
        self.progress.config(mode="indeterminate")
        self.progress.start()
        threading.Thread(target=self.uninstall_thread, daemon=True).start()

    def uninstall_thread(self):
        try:
            self.perform_uninstall()
            self.progress.stop()
            self.show_frame("uninstall_finish")
        except Exception as e:
            self.progress.stop()
            messagebox.showerror("Hata", f"Kaldırma sırasında bir hata oluştu:\n{str(e)}")
            self.show_frame("maintenance")

    def start_update(self):
        self.show_frame("action")
        self.action_title.config(text="Güncelleniyor...")
        self.progress.config(mode="determinate")
        threading.Thread(target=self.update_thread, daemon=True).start()

    def update_thread(self):
        try:
            self.progress.config(mode="indeterminate")
            self.progress.start()
            self.perform_uninstall()
            self.progress.stop()
            self.progress.config(mode="determinate")
            self.install_process()
        except Exception as e:
            messagebox.showerror("Hata", f"Güncelleme sırasında hata oluştu:\n{str(e)}")
            self.show_frame("maintenance")

    def start_installation(self):
        self.show_frame("action")
        self.action_title.config(text="Kurulum Yapılıyor...")
        self.progress.config(mode="determinate")
        threading.Thread(target=self.install_process, daemon=True).start()

    def install_process(self):
        temp_dir = os.environ['TEMP']
        zip1_path = os.path.join(temp_dir, "Golder1.zip")
        zip2_path = os.path.join(temp_dir, "Golder2.zip")

        try:
            # 1. DOSYAYI İNDİR VE BELGELERE AT
            self.status_label.config(text="Golder.zip indiriliyor (Belgeler için)...")
            self.progress["value"] = 0
            urllib.request.urlretrieve(GOLDER_DOC_URL, zip1_path, reporthook=self.update_progress)
            
            self.status_label.config(text="Belgeler klasörüne çıkartılıyor...")
            self.extract_and_move(zip1_path, TARGET_DOC_DIR)

            # 2. DOSYAYI İNDİR VE C: DİSKİNE AT
            self.status_label.config(text="Program.zip indiriliyor (C: diski için)...")
            self.progress["value"] = 0
            urllib.request.urlretrieve(GOLDER_C_URL, zip2_path, reporthook=self.update_progress)
            
            self.status_label.config(text="C:\\ diskine çıkartılıyor...")
            self.extract_and_move(zip2_path, TARGET_C_DIR)

            # 3. KISAYOLLARI OLUŞTUR
            self.status_label.config(text="Kısayollar oluşturuluyor...")
            self.progress["value"] = 100
            
            create_shortcut(SHORTCUT_TARGET, DESKTOP_SHORTCUT)
            create_shortcut(SHORTCUT_TARGET, START_MENU_SHORTCUT)

            # TEMİZLİK
            if os.path.exists(zip1_path): os.remove(zip1_path)
            if os.path.exists(zip2_path): os.remove(zip2_path)

            self.show_frame("finish")

        except Exception as e:
            messagebox.showerror("Kurulum Hatası", f"Kurulum sırasında bir hata oluştu:\n{str(e)}")
            self.show_frame("welcome")


if __name__ == "__main__":
    app = InstallerApp()
    app.mainloop()



