import sys
import subprocess
import importlib.util

def check_requirements(requirements):
    for req in requirements:
        if importlib.util.find_spec(req) is None:
            ans = input(f"Bu betiğin çalışabilmesi için {req} kütüphanesinin yüklü olması gerekir, şimdi yüklensin mi? (E/H): ")
            if ans.lower() == 'e':
                subprocess.check_call([sys.executable, "-m", "pip", "install", req])
            else:
                sys.exit(1)

check_requirements(['colorama'])

import os
import tkinter as tk
from tkinter import filedialog
import difflib
import filecmp
import colorama
from colorama import Fore

colorama.init(autoreset=True)

def truncate_line(line, max_len=80):
    line = line.strip()
    if len(line) > max_len:
        return line[:30] + " ... " + line[-30:]
    return line

def inline_diff(l1, l2):
    m = difflib.SequenceMatcher(None, l1.strip(), l2.strip())
    res = []
    for tag, i1, i2, j1, j2 in m.get_opcodes():
        if tag == 'replace':
            res.append(f"{Fore.RED}[- {l1.strip()[i1:i2]} -]{Fore.GREEN}[+ {l2.strip()[j1:j2]} +]{Fore.WHITE}")
        elif tag == 'delete':
            res.append(f"{Fore.RED}[- {l1.strip()[i1:i2]} -]{Fore.WHITE}")
        elif tag == 'insert':
            res.append(f"{Fore.GREEN}[+ {l2.strip()[j1:j2]} +]{Fore.WHITE}")
        elif tag == 'equal':
            eq = l1.strip()[i1:i2]
            if len(eq) > 40:
                eq = eq[:15] + " ... " + eq[-15:]
            res.append(f"{Fore.WHITE}{eq}")
    return "".join(res)

def compare_files(file1, file2):
    print(f"\n{Fore.CYAN}--- Dosya Karşılaştırması: {os.path.basename(file1)} ---")
    try:
        with open(file1, 'r', encoding='utf-8') as f1, open(file2, 'r', encoding='utf-8') as f2:
            lines1 = f1.readlines()
            lines2 = f2.readlines()
    except Exception:
        print(f"{Fore.RED}Dosyalar okunurken hata oluştu (İkili dosya olabilir).")
        return

    if lines1 == lines2:
        print(f"{Fore.GREEN}İçerikler tamamen aynı.")
        return

    m = difflib.SequenceMatcher(None, lines1, lines2)
    diff_count = 0

    for tag, i1, i2, j1, j2 in m.get_opcodes():
        if tag == 'equal':
            continue
            
        diff_count += 1
        if diff_count > 15:
            print(f"{Fore.YELLOW}... ve diğer farklılıklar (çok fazla olduğu için gizlendi).")
            break

        if tag == 'replace':
            if (i2 - i1) == (j2 - j1):
                for l1, l2 in zip(lines1[i1:i2], lines2[j1:j2]):
                    print(f"{Fore.YELLOW}Değişen Satır:")
                    print(f"  {inline_diff(l1, l2)}")
            else:
                for l1 in lines1[i1:i2]:
                    print(f"{Fore.RED}- {truncate_line(l1)}")
                for l2 in lines2[j1:j2]:
                    print(f"{Fore.GREEN}+ {truncate_line(l2)}")
        elif tag == 'delete':
            for l1 in lines1[i1:i2]:
                print(f"{Fore.RED}- {truncate_line(l1)}")
        elif tag == 'insert':
            for l2 in lines2[j1:j2]:
                print(f"{Fore.GREEN}+ {truncate_line(l2)}")

def compare_directories(dir1, dir2):
    print(f"\n{Fore.CYAN}=== Klasör Karşılaştırması ===")
    print(f"{Fore.CYAN}1: {dir1}")
    print(f"{Fore.CYAN}2: {dir2}")
    _compare_dirs_recursive(filecmp.dircmp(dir1, dir2))

def _compare_dirs_recursive(dcmp):
    for name in dcmp.left_only:
        print(f"{Fore.RED}Sadece 1. klasörde: {os.path.join(dcmp.left, name)}")
        
    for name in dcmp.right_only:
        print(f"{Fore.GREEN}Sadece 2. klasörde: {os.path.join(dcmp.right, name)}")
        
    for name in dcmp.diff_files:
        f1 = os.path.join(dcmp.left, name)
        f2 = os.path.join(dcmp.right, name)
        print(f"\n{Fore.YELLOW}Farklı dosya: {name}")
        compare_files(f1, f2)
        
    for sub_dcmp in dcmp.subdirs.values():
        _compare_dirs_recursive(sub_dcmp)

def main():
    root = tk.Tk()
    root.withdraw()
    top = tk.Toplevel(root)
    top.title("Seçim")
    top.geometry("300x150")
    sel_type = [None]

    def set_file():
        sel_type[0] = 'file'
        top.destroy()

    def set_dir():
        sel_type[0] = 'dir'
        top.destroy()

    tk.Label(top, text="Lütfen karşılaştırmak istediğiniz türü seçin:").pack(pady=15)
    tk.Button(top, text="Dosya Karşılaştır", command=set_file, width=20).pack(pady=5)
    tk.Button(top, text="Klasör Karşılaştır", command=set_dir, width=20).pack(pady=5)

    root.wait_window(top)

    if not sel_type[0]:
        sys.exit(0)

    path1 = None
    path2 = None

    if sel_type[0] == 'file':
        path1 = filedialog.askopenfilename(title="1. Dosyayı Seçin")
        if path1:
            path2 = filedialog.askopenfilename(title="2. Dosyayı Seçin")
        if path1 and path2:
            compare_files(path1, path2)
            
    elif sel_type[0] == 'dir':
        path1 = filedialog.askdirectory(title="1. Klasörü Seçin")
        if path1:
            path2 = filedialog.askdirectory(title="2. Klasörü Seçin")
        if path1 and path2:
            compare_directories(path1, path2)

    root.destroy()
    
    input(f"\n{Fore.CYAN}İşlem tamamlandı. Çıkmak için Enter'a basın...")

if __name__ == "__main__":
    main()