#!/usr/bin/env python3
"""
Bulk Text Cleaning & Filtering Tool with Character Count Filtering
Membaca semua file .txt dari folder 'Source', memprosesnya berdasarkan
filter kata, karakter, bad/contain words, menghapus duplikat, dan menyimpannya ke folder 'Output'.
"""

import json
import os
import sys
from pathlib import Path
from typing import List, Set


def load_list_from_file(file_path: Path) -> List[str]:
    """Membaca file kata kunci/bad words (lowercase & hapus baris kosong/komentar)."""
    if not file_path.exists():
        return []
    
    with open(file_path, "r", encoding="utf-8") as f:
        return [
            line.strip().lower() 
            for line in f 
            if line.strip() and not line.strip().startswith("#")
        ]


def load_config(config_path: Path) -> dict:
    """Membaca konfigurasi JSON."""
    if not config_path.exists():
        print(f"❌ Error: File '{config_path.name}' tidak ditemukan.", file=sys.stderr)
        sys.exit(1)
        
    with open(config_path, "r", encoding="utf-8") as f:
        return json.load(f)


def process_lines(
    lines: List[str],
    config: dict,
    bad_words: List[str],
    contain_words: List[str]
) -> List[str]:
    """Proses filtering, formatting, dan remove duplicate teks per baris."""
    filtered_lines = []
    
    # Ambil parameter dari config
    min_words = config.get("min_words", 1)
    max_words = config.get("max_words", None)
    min_chars = config.get("min_chars", None)
    max_chars = config.get("max_chars", None)
    
    skip_empty = config.get("skip_empty_lines", True)
    remove_dup = config.get("remove_duplicates", True)
    prepend = config.get("prepend_text", "")
    append = config.get("append_text", "")
    insert_pos = config.get("insert_position", None)
    insert_txt = config.get("insert_text", "")

    seen_lines = set()
    output_counter = 1

    for line in lines:
        line_str = line.strip() if skip_empty else line.rstrip("\r\n")
        
        # 1. Skip baris kosong
        if skip_empty and not line_str:
            continue
            
        # 2. Filter Jumlah Karakter (Character Count)
        char_count = len(line_str)
        if min_chars is not None and char_count < min_chars:
            continue
        if max_chars is not None and max_chars > 0 and char_count > max_chars:
            continue

        # 3. Filter Jumlah Kata (Word Count)
        words = line_str.split()
        word_count = len(words)
        
        if word_count < min_words:
            continue
        if max_words is not None and max_words > 0 and word_count > max_words:
            continue
            
        line_lower = line_str.lower()
        
        # 4. Filter Bad Words
        if bad_words and any(bw in line_lower for bw in bad_words):
            continue
            
        # 5. Filter Contain Words
        if contain_words and not any(cw in line_lower for cw in contain_words):
            continue

        # 6. Remove Duplicates
        if remove_dup:
            if line_lower in seen_lines:
                continue
            seen_lines.add(line_lower)
                
        # 7. Insert Text pada posisi kata tertentu (1-based index)
        if insert_pos and insert_txt and len(words) >= insert_pos:
            idx = insert_pos - 1
            words.insert(idx, insert_txt)
            processed_line = " ".join(words)
        else:
            processed_line = line_str

        # 8. Prepend & Append (dengan tag {line})
        cur_prepend = prepend.replace("{line}", str(output_counter)) if prepend else ""
        cur_append = append.replace("{line}", str(output_counter)) if append else ""
        
        final_line = f"{cur_prepend}{processed_line}{cur_append}"
        filtered_lines.append(final_line)
        
        output_counter += 1

    return filtered_lines

def main():
    # Menentukan root folder
    base_dir = Path(__file__).resolve().parent

    # File & Folder Paths
    source_dir = base_dir / "Input"  # Diubah dari "Source" menjadi "Input"
    output_dir = base_dir / "Output"
    config_file = base_dir / "config.json"
    bad_words_file = base_dir / "bad_words.txt"
    contain_words_file = base_dir / "contain_words.txt"

    output_dir.mkdir(parents=True, exist_ok=True)

    config = load_config(config_file)
    bad_words = load_list_from_file(bad_words_file)
    contain_words = load_list_from_file(contain_words_file)

    print("==================================================")
    print("           TEXT CLEANER & FILTER (BULK)           ")
    print("==================================================")
    print(f"⚙️ Config Dimuat    : {config_file.name}")
    print(f"📏 Min/Max Kata     : {config.get('min_words', 1)} / {config.get('max_words', 'Bebas')}")
    print(f"🔤 Min/Max Karakter : {config.get('min_chars', 'Bebas')} / {config.get('max_chars', 'Bebas')}")
    print(f"🔄 Remove Duplicates: {'AKTIF' if config.get('remove_duplicates', True) else 'NONAKTIF'}")
    print(f"🚫 Bad Words        : {len(bad_words)} kata/frasa")
    print(f"🔍 Contain Words    : {len(contain_words)} kata/frasa")
    print("--------------------------------------------------")

    txt_files = list(source_dir.glob("*.txt"))

    if not txt_files:
        print(f"⚠️ Tidak ada file '.txt' ditemukan di dalam folder '{source_dir.name}/'.")
        return

    total_processed_files = 0
    for txt_file in txt_files:
        print(f"⏳ Memproses: {txt_file.name} ... ", end="")

        try:
            with open(txt_file, "r", encoding="utf-8") as f:
                raw_lines = f.readlines()

            result_lines = process_lines(raw_lines, config, bad_words, contain_words)

            destination_path = output_dir / txt_file.name
            with open(destination_path, "w", encoding="utf-8") as f:
                f.write("\n".join(result_lines) + ("\n" if result_lines else ""))

            print(f"✅ Selesai ({len(raw_lines)} -> {len(result_lines)} baris)")
            total_processed_files += 1

        except Exception as e:
            print(f"❌ Gagal ({e})")

    print("--------------------------------------------------")
    print(f"🎉 Selesai! {total_processed_files} file berhasil difilter dan disimpan di folder 'Output/'.\n")


if __name__ == "__main__":
    main()