import argparse
import sys
import json
from datetime import datetime
from pathlib import Path
from .api.load import load_jsonl
from .api.verify import verify, template_diff, check_time_limit
from .api.build import reconstruct_file_from_events


def main():
    parser = argparse.ArgumentParser(
        description="Process and verify code recorder JSONL files"
    )
    parser.add_argument(
        "jsonl_file",
        type=Path,
        help="Path to the compressed JSONL file (*.recording.jsonl.gz)",
    )
    parser.add_argument(
        "template_file",
        type=Path,
        help="Path to the initial template file that was recorded",
    )
    parser.add_argument(
        "--time-limit",
        type=int,
        default=None,
        help="Maximum allowed time in minutes between first and last edit. If exceeded, recording is flagged.",
    )
    parser.add_argument(
        "--document",
        type=str,
        default=None,
        help=("Document path or filename to process from the recording. "
              "Defaults to the document whose extension matches the template file."),
    )
    parser.add_argument(
        "--output-json",
        type=Path,
        default=None,
        help="Path to output JSON file with verification results (time info and suspicious events).",
    )

    args = parser.parse_args()

    # Load JSONL file first to get document path
    try:
        jsonData = load_jsonl(args.jsonl_file)
    except FileNotFoundError as e:
        print(f"Error: {e}", file=sys.stderr)
        return 1
    except (ValueError, IOError) as e:
        print(f"Error loading JSONL file: {e}", file=sys.stderr)
        return 1

    # Decide which recorded document to process
    documents = {e.get("document") for e in jsonData if "document" in e and e.get("document") is not None}
    recorded_docs = sorted([d for d in documents if d is not None])

    def resolve_document(docs: list[str], template_path: Path, override: str | None) -> str | None:
        if not docs:
            return None

        if override:
            matches = [d for d in docs if d.endswith(override) or Path(d).name == override]
            if not matches:
                raise ValueError(
                    f"No document in recording matches '{override}'. Available: {docs}"
                )
            if len(matches) > 1:
                raise ValueError(
                    f"Ambiguous document override '{override}'. Matches: {matches}"
                )
            return matches[0]

        template_ext = template_path.suffix
        ext_matches = [d for d in docs if Path(d).suffix == template_ext]
        if len(ext_matches) == 1:
            return ext_matches[0]
        if len(ext_matches) > 1:
            raise ValueError(
                f"Multiple documents share extension '{template_ext}': {ext_matches}. "
                "Use --document to choose one."
            )

        if len(docs) == 1:
            return docs[0]

        raise ValueError(
            "Could not determine document to process. Use --document to select one. "
            f"Available documents: {docs}"
        )

    try:
        target_document = resolve_document(recorded_docs, args.template_file, args.document)
    except ValueError as e:
        print(f"Error determining document: {e}", file=sys.stderr)
        return 1

    if target_document:
        doc_events = tuple(e for e in jsonData if e.get("document") == target_document)
        if not doc_events:
            print(f"Error: No events found for document '{target_document}'", file=sys.stderr)
            return 1
    else:
        doc_events = jsonData

    print(f"Processing: {target_document or args.template_file}", file=sys.stderr)

    # Read template file
    try:
        templateData = args.template_file.read_text()
    except FileNotFoundError:
        print(f"Error: Template file not found: {args.template_file}", file=sys.stderr)
        return 1
    except Exception as e:
        print(f"Error reading template file: {e}", file=sys.stderr)
        return 1

    # Check time limit and display elapsed time
    time_info = check_time_limit(doc_events, args.time_limit)
    if time_info:
        print(f"Elapsed editing time: {time_info['minutes_elapsed']} minutes", file=sys.stderr)
        print(f"Time span (first to last edit): {(datetime.fromisoformat(time_info['last_timestamp'].replace('Z', '+00:00')) - datetime.fromisoformat(time_info['first_timestamp'].replace('Z', '+00:00'))).total_seconds() / 60:.2f} minutes", file=sys.stderr)
        if time_info['exceeds_limit']:
            print(f"\nTime limit exceeded!", file=sys.stderr)
            print(f"  Limit: {time_info['time_limit_minutes']} minutes", file=sys.stderr)
            print(f"  First edit: {time_info['first_timestamp']}", file=sys.stderr)
            print(f"  Last edit: {time_info['last_timestamp']}", file=sys.stderr)

    # Verify and process
    try:
        templateData, suspicious_events = verify(templateData, doc_events)
        print(reconstruct_file_from_events(doc_events, templateData, document_path=target_document))

        # Prepare results for JSON output
        results = {
            "document": target_document or str(args.template_file),
            "time_info": time_info,
            "suspicious_events": suspicious_events,
        }

        if suspicious_events:
            print("\nSuspicious copy-paste events detected:", file=sys.stderr)
            for ev in suspicious_events:
                reason = ev.get('reason', 'unknown')
                indices = ev.get('event_indices', [ev['event_index']])
                if len(indices) > 1:
                    print(f"  Events #{indices[0]}-#{indices[-1]} ({reason}): "
                          f"{ev['line_count']} lines, {ev['char_count']} chars", file=sys.stderr)
                else:
                    print(f"  Event #{ev['event_index']} ({reason}): "
                          f"{ev['line_count']} lines, {ev['char_count']} chars - "
                          f"newFragment: {ev['newFragment']}", file=sys.stderr)
        else:
            print("Success! No suspicious events detected.", file=sys.stderr)

        # Write JSON output if requested
        if args.output_json:
            try:
                args.output_json.parent.mkdir(parents=True, exist_ok=True)
                with open(args.output_json, 'w') as f:
                    json.dump(results, f, indent=2)
                print(f"Results written to {args.output_json}", file=sys.stderr)
            except Exception as e:
                print(f"Error writing JSON output: {e}", file=sys.stderr)
                return 1
    except ValueError as e:
        print("File failed verification from template!", file=sys.stderr)
        print(str(e), file=sys.stderr)
        try:
            print(template_diff(templateData, doc_events), file=sys.stderr)
        except Exception:
            pass
        return 1
    except Exception as e:
        print(f"Error processing file: {type(e).__name__}: {e}", file=sys.stderr)
        return 1


if __name__ == "__main__":
    sys.exit(main())
