#!/usr/bin/env python3
"""Merge all .txt files from a source folder into a single output file.

Usage:
  python merge_protagonists.py --src "WikiServ/Картотека/Персонажи/Протагонисты" --out "WikiServ/Протагонисты_merged.txt"

The script attempts to read files as UTF-8, falls back to CP1251 when needed,
and writes the combined output as UTF-8. It skips the output file if it would
otherwise be included in the input list.
"""
from __future__ import annotations

import argparse
import os
from pathlib import Path
from typing import List


def find_txt_files(src: str) -> List[str]:
    p = Path(src)
    files: List[str] = []
    if not p.exists():
        return files
    for fp in sorted(p.rglob('*.txt')):
        if fp.is_file():
            files.append(str(fp))
    return files


def read_text_file(path: str) -> str:
    # Try utf-8 then cp1251, finally fallback with replace
    try:
        with open(path, 'r', encoding='utf-8') as f:
            return f.read()
    except UnicodeDecodeError:
        try:
            with open(path, 'r', encoding='cp1251') as f:
                return f.read()
        except Exception:
            with open(path, 'rb') as f:
                return f.read().decode('utf-8', errors='replace')


def merge_txt_files(src: str, out: str, add_header: bool = True) -> int:
    src_path = Path(src)
    out_path = Path(out)

    files = find_txt_files(str(src_path))
    # exclude output file if it's inside source directory or same path
    files = [f for f in files if Path(f).resolve() != out_path.resolve()]

    if not files:
        return 0

    out_path.parent.mkdir(parents=True, exist_ok=True)
    written = 0
    with open(out_path, 'w', encoding='utf-8') as outf:
        for f in files:
            try:
                text = read_text_file(f)
            except Exception as e:
                text = f"\n<<ERROR reading {f}: {e}>>\n"
            if add_header:
                rel = os.path.relpath(f, start=src)
                outf.write(f"\n\n=== File: {rel} ===\n\n")
            outf.write(text)
            written += 1
    return written


def main() -> None:
    parser = argparse.ArgumentParser(description='Merge .txt files from a folder')
    parser.add_argument('--src', '-s', default='WikiServ/Картотека/Персонажи/Протагонисты', help='Source folder')
    parser.add_argument('--out', '-o', default='WikiServ/Протагонисты_merged.txt', help='Output file')
    parser.add_argument('--no-header', action='store_true', help='Do not add filename headers between files')

    args = parser.parse_args()
    count = merge_txt_files(args.src, args.out, add_header=not args.no_header)
    print(f"Merged {count} files into {args.out}")


if __name__ == '__main__':
    main()
