"""
Management command to manually fetch patient data from HIS system.

Usage:
    python manage.py fetch_his_surveys [--minutes N] [--from-date DATE] [--to-date DATE] [--test]

Options:
    --minutes N        Fetch patients from the last N minutes (default: 10)
    --from-date DATE   Fetch patients from this date (DD-Mon-YYYY HH:MM:SS)
    --to-date DATE     Fetch patients until this date (DD-Mon-YYYY HH:MM:SS)
    --test             Test connection only, don't fetch data
    --config NAME      Configuration name to use (optional)

Examples:
    # Relative: last 10 minutes
    python manage.py fetch_his_surveys --minutes 10

    # Absolute: simulate a date range (for testing against test endpoint)
    python manage.py fetch_his_surveys --config "HIS Test" \
        --from-date "01-Jan-2026 00:00:00" --to-date "01-Jan-2026 02:00:00"

    # Test connection
    python manage.py fetch_his_surveys --config "HIS Test" --test
"""

from django.core.management.base import BaseCommand
from django.utils import timezone

from apps.integrations.services.his_client import HISClient, HISClientFactory
from apps.integrations.services.his_adapter import HISAdapter


class Command(BaseCommand):
    help = "Fetch patient data from HIS system"

    def add_arguments(self, parser):
        parser.add_argument(
            "--minutes",
            type=int,
            default=10,
            help="Fetch patients from the last N minutes (default: 10)",
        )
        parser.add_argument(
            "--from-date",
            type=str,
            default=None,
            help="Fetch patients from this date (DD-Mon-YYYY HH:MM:SS)",
        )
        parser.add_argument(
            "--to-date",
            type=str,
            default=None,
            help="Fetch patients until this date (DD-Mon-YYYY HH:MM:SS)",
        )
        parser.add_argument(
            "--test",
            action="store_true",
            help="Test connection only, don't fetch data",
        )
        parser.add_argument(
            "--config",
            type=str,
            help="Configuration name to use (optional)",
        )

    def handle(self, *args, **options):
        minutes = options["minutes"]
        from_date_str = options.get("from_date")
        to_date_str = options.get("to_date")
        test_only = options["test"]
        config_name = options.get("config")

        self.stdout.write(self.style.MIGRATE_HEADING("=" * 70))
        self.stdout.write(self.style.MIGRATE_HEADING("HIS Patient Data Fetch"))
        self.stdout.write(self.style.MIGRATE_HEADING("=" * 70))

        if from_date_str and to_date_str:
            self.stdout.write(f"Mode: custom date range")
            self.stdout.write(f"  From: {from_date_str}")
            self.stdout.write(f"  To:   {to_date_str}")
        else:
            self.stdout.write(f"Mode: relative (last {minutes} minutes)")

        if config_name:
            from apps.integrations.models import IntegrationConfig

            config = IntegrationConfig.objects.filter(name=config_name).first()
            if not config:
                self.stdout.write(self.style.ERROR(f'Configuration "{config_name}" not found'))
                return
            clients = [HISClient(config)]
        else:
            clients = HISClientFactory.get_all_active_clients()

        if not clients:
            self.stdout.write(self.style.ERROR("No active HIS configurations found"))
            return

        self.stdout.write(f"Found {len(clients)} HIS configuration(s)")

        total_patients = 0
        total_visits_saved = 0
        total_surveys_created = 0

        for client in clients:
            config_display = client.config.name if client.config else "Default"
            self.stdout.write(self.style.MIGRATE_HEADING(f"\nConfiguration: {config_display}"))

            self.stdout.write("Testing connection...", ending=" ")
            test_result = client.test_connection()

            if test_result["success"]:
                self.stdout.write(self.style.SUCCESS("Connected"))
            else:
                self.stdout.write(self.style.ERROR(f"Failed: {test_result['message']}"))
                continue

            if test_only:
                continue

            from datetime import timedelta
            from apps.integrations.tasks import _parse_his_date

            if from_date_str and to_date_str:
                fetch_since = _parse_his_date(from_date_str)
                fetch_until = _parse_his_date(to_date_str)
                if not fetch_since or not fetch_until:
                    self.stdout.write(self.style.ERROR("Invalid date format. Use DD-Mon-YYYY HH:MM:SS"))
                    return
                time_display = f"{fetch_since.strftime('%Y-%m-%d %H:%M')} to {fetch_until.strftime('%Y-%m-%d %H:%M')}"
            else:
                fetch_since = timezone.now() - timedelta(minutes=minutes)
                fetch_until = None
                time_display = f"{fetch_since.strftime('%Y-%m-%d %H:%M:%S')}"

            self.stdout.write(f"Fetching patient data: {time_display}")

            his_data = client.fetch_patient_data(since=fetch_since, until=fetch_until)

            if not his_data:
                self.stdout.write(self.style.WARNING("No data returned from HIS"))
                continue

            patient_list = his_data.get("FetchPatientDataTimeStampList", [])

            if not patient_list:
                self.stdout.write(self.style.WARNING("No patients found"))
                continue

            self.stdout.write(f"Found {len(patient_list)} patient(s)")

            process_result = HISAdapter.process_his_response(his_data)

            total_patients += len(patient_list)
            total_visits_saved += process_result.get("visits_saved", 0)
            total_surveys_created += process_result.get("surveys_created", 0)

            for detail in process_result.get("details", []):
                name = detail.get("patient_name", "Unknown")
                ptype = detail.get("patient_type", "")
                adm_id = detail.get("admission_id", "")

                if detail.get("survey_created"):
                    self.stdout.write(f"  {self.style.SUCCESS('+')} {name} ({ptype}) adm={adm_id} - survey created")
                elif detail.get("error"):
                    self.stdout.write(f"  {self.style.ERROR('x')} {name} ({ptype}) adm={adm_id} - {detail['error']}")
                else:
                    reason = detail.get("reason", "Visit in progress")
                    self.stdout.write(f"  - {name} ({ptype}) adm={adm_id} - {reason}")

            if process_result.get("errors"):
                for err in process_result["errors"]:
                    self.stdout.write(self.style.WARNING(f"  Error: {err}"))

            if client.config:
                client.config.last_sync_at = timezone.now()
                client.config.save(update_fields=["last_sync_at"])

        self.stdout.write(self.style.MIGRATE_HEADING("\n" + "=" * 70))
        self.stdout.write(self.style.MIGRATE_HEADING("Summary"))
        self.stdout.write(self.style.MIGRATE_HEADING("=" * 70))
        self.stdout.write(f"Total patients fetched: {total_patients}")
        self.stdout.write(f"Visits saved/updated:    {total_visits_saved}")
        self.stdout.write(f"Surveys created:         {total_surveys_created}")

        if test_only:
            self.stdout.write(self.style.SUCCESS("\nConnection test completed successfully!"))
        else:
            self.stdout.write(self.style.SUCCESS("\nFetch completed!"))
