from __future__ import annotations

import argparse
from pathlib import Path

from ..services import (
    ChecklistService,
    ExtractionService,
    IntakeService,
    OccupationService,
    ReportService,
    TimelineService,
    VerificationService,
)


def build_parser() -> argparse.ArgumentParser:
    parser = argparse.ArgumentParser(
        prog="migration-evidence-builder",
        description="CLI-first migration evidence processing app.",
    )
    parser.add_argument(
        "--storage-root",
        default=None,
        help="Override default storage root (defaults to flask_server/storage/applicants).",
    )

    sub = parser.add_subparsers(dest="command", required=True)

    init_cmd = sub.add_parser("init-applicant", help="Create applicant folder scaffold.")
    init_cmd.add_argument("applicant_id", nargs="?")
    init_cmd.add_argument("--applicant", dest="applicant_opt", default=None)
    init_cmd.add_argument("--full-name", default="")
    init_cmd.add_argument("--sponsor-name", default="")
    init_cmd.add_argument("--nominated-occupation", default="")

    for name, help_text in [
        ("scan-intake", "Scan intake/* and register documents."),
        ("process-documents", "Process all scanned documents once into canonical outputs."),
        ("build-timeline", "Generate applicant timeline output."),
        ("analyze-occupations", "Generate occupation support analysis output."),
        ("generate-cv", "Generate draft CV output."),
        ("generate-gap-report", "Generate timeline gap report output."),
        ("generate-chatgpt-pack", "Generate ChatGPT briefing pack output."),
        ("generate-checklist", "Generate evidence checklist output."),
    ]:
        cmd = sub.add_parser(name, help=help_text)
        cmd.add_argument("applicant_id", nargs="?")
        cmd.add_argument("--applicant", dest="applicant_opt", default=None)

    confirm_cmd = sub.add_parser("confirm-document", help="Confirm a processed document after manual verification.")
    confirm_cmd.add_argument("applicant_id", nargs="?")
    confirm_cmd.add_argument("--applicant", dest="applicant_opt", default=None)
    confirm_cmd.add_argument(
        "--document-path",
        required=True,
        help="Relative path under applicant root, e.g. identity/passport/2026-04-13_passport-bio-page",
    )
    confirm_cmd.add_argument(
        "--field",
        action="append",
        default=[],
        help="Field path in document.json to confirm. Repeatable. Example: --field identifiers.passport_number",
    )
    confirm_cmd.add_argument("--note", default="", help="Manual reviewer note.")
    confirm_cmd.add_argument("--by", dest="confirmed_by", default="manual_reviewer", help="Reviewer identifier.")

    return parser


def _resolve_applicant_id(args: argparse.Namespace, parser: argparse.ArgumentParser) -> str:
    applicant_id = getattr(args, "applicant_id", None) or getattr(args, "applicant_opt", None)
    if not applicant_id:
        parser.error("Missing applicant_id. Use positional <applicant_id> or --applicant <id>.")
    return str(applicant_id).strip()


def main() -> None:
    parser = build_parser()
    args = parser.parse_args()

    storage_root = Path(args.storage_root) if args.storage_root else None
    intake_service = IntakeService(storage_root=storage_root)
    applicant_id = _resolve_applicant_id(args, parser)

    if args.command == "init-applicant":
        path = intake_service.init_applicant(
            applicant_id=applicant_id,
            full_name=args.full_name,
            sponsor_name=args.sponsor_name,
            nominated_occupation=args.nominated_occupation,
        )
        print(f"Applicant initialized: {path}")
        return

    applicant_base = intake_service.applicant_path(applicant_id)

    if args.command == "scan-intake":
        manifests = intake_service.scan_intake(applicant_id)
        print(f"Documents scanned: {len(manifests)}")
        for item in manifests:
            print(f"- {item['doc_id']} [{item['category']}] -> {item['stored_original']}")
        return

    if args.command == "process-documents":
        extractor = ExtractionService()
        processed = []
        for manifest_path in intake_service.list_document_manifests(applicant_id):
            processed.append(extractor.process_document(manifest_path))
        print(f"Documents processed: {len(processed)}")
        for row in processed:
            print(f"- {row['doc_id']} [{row['category']}]")
        return

    if args.command == "build-timeline":
        output = TimelineService().build_timeline(applicant_base)
        print(f"Timeline generated with {len(output.get('events', []))} events")
        return

    if args.command == "analyze-occupations":
        output = OccupationService().analyze(applicant_base)
        print("Occupation analysis generated")
        print(f"Detected keywords: {', '.join(output.get('detected_keywords', [])) or 'none'}")
        return

    if args.command == "generate-cv":
        output = ReportService().generate_cv(applicant_base)
        print(f"CV generated: {output}")
        return

    if args.command == "generate-gap-report":
        output = ReportService().generate_gap_report(applicant_base)
        print(f"Gap report generated: {output}")
        return

    if args.command == "generate-chatgpt-pack":
        output = ReportService().generate_chatgpt_pack(applicant_base)
        print(f"ChatGPT pack generated: {output}")
        return

    if args.command == "generate-checklist":
        output = ChecklistService().generate(applicant_base)
        print(f"Checklist generated with {len(output.get('items', []))} items")
        return

    if args.command == "confirm-document":
        result = VerificationService().confirm_document(
            applicant_base=applicant_base,
            document_path=args.document_path,
            verified_fields=args.field,
            note=args.note,
            confirmed_by=args.confirmed_by,
        )
        print(f"Document confirmed: {result['document_path']}")
        print(f"Status: {result['status']}")
        print(f"Fields confirmed: {len(result['confirmed_fields'])}")
        return

    parser.error(f"Unknown command: {args.command}")


if __name__ == "__main__":
    main()
