"""
Seed today's test data for HIS integration cron testing.

Creates ~20 patients with recent timestamps so the 5-minute
fetch_his_surveys cron will pick them up.

Usage:
    python manage.py seed_his_today_data [--clear]
"""

import copy
import random
import string

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


SEED_PREFIX = "SEED"


ED_EVENTS = [
    ("Consultation", 0),
    ("Doctor assignment", 5),
    ("Drug Prescription", 10),
    ("End Of the Episode", 15),
]

IP_EVENTS = [
    ("IP Admissions", 0),
    ("Bed Allocation", 2),
    ("Fit for discharge", 60),
    ("Discharge date", 65),
    ("Discharge followUp", 63),
    ("IP Bill", 67),
]

OP_EVENTS = [
    ("Consultation", 0),
    ("Doctor Visited", 3),
    ("Rad Prescription", 8),
    ("Radiology Bill", 10),
    ("Radiology Token", 10),
    ("Radiology Patient Arrived", 15),
    ("Radiology Examination completed", 20),
]

PATIENT_SCENARIOS = [
    {"type": "ED", "discharged": True, "admit_min_ago": 90, "discharge_min_ago": 75},
    {"type": "ED", "discharged": True, "admit_min_ago": 60, "discharge_min_ago": 45},
    {"type": "ED", "discharged": True, "admit_min_ago": 30, "discharge_min_ago": 15},
    {"type": "ED", "discharged": True, "admit_min_ago": 15, "discharge_min_ago": 10},
    {"type": "ED", "discharged": False, "admit_min_ago": 20, "discharge_min_ago": None},
    {"type": "ED", "discharged": False, "admit_min_ago": 8, "discharge_min_ago": None},
    {"type": "IP", "discharged": True, "admit_min_ago": 120, "discharge_min_ago": 60},
    {"type": "IP", "discharged": True, "admit_min_ago": 90, "discharge_min_ago": 30},
    {"type": "IP", "discharged": True, "admit_min_ago": 60, "discharge_min_ago": 10},
    {"type": "IP", "discharged": True, "admit_min_ago": 45, "discharge_min_ago": 5},
    {"type": "IP", "discharged": False, "admit_min_ago": 90, "discharge_min_ago": None},
    {"type": "IP", "discharged": False, "admit_min_ago": 30, "discharge_min_ago": None},
    {"type": "OP", "discharged": True, "admit_min_ago": 200, "discharge_min_ago": None, "last_event_min_ago": 180},
    {"type": "OP", "discharged": True, "admit_min_ago": 150, "discharge_min_ago": None, "last_event_min_ago": 120},
    {"type": "OP", "discharged": True, "admit_min_ago": 120, "discharge_min_ago": None, "last_event_min_ago": 90},
    {"type": "OP", "discharged": False, "admit_min_ago": 30, "discharge_min_ago": None, "last_event_min_ago": 10},
    {"type": "OP", "discharged": False, "admit_min_ago": 15, "discharge_min_ago": None, "last_event_min_ago": 5},
    {"type": "OP", "discharged": False, "admit_min_ago": 8, "discharge_min_ago": None, "last_event_min_ago": 3},
]


def _generate_admission_id(index):
    suffix = "".join(random.choices(string.digits, k=6))
    return f"{SEED_PREFIX}-{index}-{suffix}"


def _format_his_date(dt):
    return dt.strftime("%d-%b-%Y %H:%M")


class Command(BaseCommand):
    help = "Seed today's test data for HIS cron testing"

    def add_arguments(self, parser):
        parser.add_argument("--clear", action="store_true", help="Remove previously seeded data")

    def handle(self, *args, **options):
        from apps.integrations.models import HISTestPatient, HISTestVisit

        if options["clear"]:
            deleted_p, _ = HISTestPatient.objects.filter(admission_id__startswith=SEED_PREFIX).delete()
            deleted_v, _ = HISTestVisit.objects.filter(admission_id__startswith=SEED_PREFIX).delete()
            self.stdout.write(f"Cleared {deleted_p} patients, {deleted_v} visits")
            return

        self.stdout.write(self.style.MIGRATE_HEADING("=" * 60))
        self.stdout.write(self.style.MIGRATE_HEADING("Seed Today's HIS Test Data"))
        self.stdout.write(self.style.MIGRATE_HEADING("=" * 60))

        now = timezone.now()

        existing = list(HISTestPatient.objects.exclude(admission_id__startswith=SEED_PREFIX).order_by("?")[:18])

        if len(existing) < 18:
            self.stderr.write(self.style.ERROR("Not enough source patients. Run load_his_test_data first."))
            return

        self.stdout.write(f"Source patients available: {len(existing)}")

        patients_batch = []
        visits_batch = []
        summary = {"ED": 0, "IP": 0, "OP": 0}

        for i, scenario in enumerate(PATIENT_SCENARIOS):
            source = existing[i % len(existing)]
            pt_type = scenario["type"]
            summary[pt_type] = summary.get(pt_type, 0) + 1

            admit_date = now - timezone.timedelta(minutes=scenario["admit_min_ago"])
            admission_id = _generate_admission_id(i)

            patient_data = copy.deepcopy(source.patient_data)
            patient_data["AdmissionID"] = admission_id
            patient_data["AdmitDate"] = _format_his_date(admit_date)
            patient_data["PatientType"] = pt_type
            patient_data["PatientTypeID"] = {"ED": "3", "IP": "2", "OP": "1"}[pt_type]

            if scenario["discharged"] and scenario.get("discharge_min_ago"):
                discharge_date = now - timezone.timedelta(minutes=scenario["discharge_min_ago"])
                patient_data["DischargeDate"] = _format_his_date(discharge_date)
            else:
                discharge_date = None
                patient_data["DischargeDate"] = None

            patients_batch.append(
                HISTestPatient(
                    admission_id=admission_id,
                    patient_id=source.patient_id,
                    patient_type=pt_type,
                    reg_code=source.reg_code,
                    ssn=source.ssn,
                    mobile_no=source.mobile_no,
                    admit_date=admit_date,
                    discharge_date=discharge_date,
                    patient_data=patient_data,
                    hospital_id=source.hospital_id,
                    hospital_name=source.hospital_name,
                    patient_name=source.patient_name,
                )
            )

            visit_category = {"ED": "ED", "IP": "IP", "OP": "OP"}[pt_type]
            patient_type_visit = {"ED": "ER", "IP": "IP", "OP": "OP"}[pt_type]
            events = {"ED": ED_EVENTS, "IP": IP_EVENTS, "OP": OP_EVENTS}[pt_type]

            last_event_min_ago = scenario.get("last_event_min_ago")
            if last_event_min_ago is None:
                if scenario["discharged"] and scenario.get("discharge_min_ago"):
                    last_event_min_ago = scenario["discharge_min_ago"]
                else:
                    last_event_min_ago = max(scenario["admit_min_ago"] - 5, 1)

            for j, (event_name, offset_min) in enumerate(events):
                if not scenario["discharged"] and event_name in (
                    "Fit for discharge",
                    "Discharge date",
                    "Discharge followUp",
                    "IP Bill",
                    "End Of the Episode",
                ):
                    continue

                if pt_type == "OP" and not scenario["discharged"] and j == len(events) - 1:
                    event_date = now - timezone.timedelta(minutes=last_event_min_ago)
                else:
                    event_date = admit_date + timezone.timedelta(minutes=offset_min)

                visit_data = {
                    "PatientType": patient_type_visit,
                    "Type": event_name,
                    "BillDate": _format_his_date(event_date),
                    "AdmissionID": admission_id,
                    "PatientID": source.patient_id,
                    "RegCode": source.reg_code,
                    "SSN": source.ssn,
                    "MobileNo": source.mobile_no,
                }

                visits_batch.append(
                    HISTestVisit(
                        admission_id=admission_id,
                        patient_id=source.patient_id,
                        visit_category=visit_category,
                        event_type=event_name,
                        bill_date=event_date,
                        reg_code=source.reg_code,
                        ssn=source.ssn,
                        mobile_no=source.mobile_no,
                        visit_data=visit_data,
                    )
                )

        HISTestPatient.objects.bulk_create(patients_batch, batch_size=1000)
        self.stdout.write(f"Created {len(patients_batch)} patients")

        HISTestVisit.objects.bulk_create(visits_batch, batch_size=2000)
        self.stdout.write(f"Created {len(visits_batch)} visits")

        self.stdout.write(self.style.MIGRATE_HEADING("\nSummary"))
        self.stdout.write(f"  ED: {summary['ED']} (4 discharged, 2 active)")
        self.stdout.write(f"  IP: {summary['IP']} (4 discharged, 2 active)")
        self.stdout.write(f"  OP: {summary['OP']} (3 complete, 3 in progress)")
        self.stdout.write(self.style.SUCCESS("\nDone! Run fetch_his_surveys to test."))
