from datetime import date

from django.contrib.auth import get_user_model
from django.core.management.base import BaseCommand
from django.db import transaction
from django.db.models.signals import post_save, pre_save

from apps.accounts.models import ClientProfile
from apps.projects.models import ProjectBrief, ProjectInternalNote
from apps.projects.signals import capture_previous_status, handle_brief_notifications


CLIENTS = [
    {
        "username": "client1",
        "email": "client1@example.com",
        "first_name": "Alex",
        "last_name": "Morgan",
        "password": "ClientDemo2026!",
        "company": "Northside Imaging Lab",
        "phone": "+1 604 555 0101",
    },
    {
        "username": "sarah.research",
        "email": "sarah.research@example.com",
        "first_name": "Sarah",
        "last_name": "Chen",
        "password": "ClientDemo2026!",
        "company": "Pacific Oncology Research",
        "phone": "+1 604 555 0102",
    },
    {
        "username": "devteam",
        "email": "devteam@example.com",
        "first_name": "Jordan",
        "last_name": "Lee",
        "password": "ClientDemo2026!",
        "company": "BioFlow Analytics",
        "phone": "+44 20 7946 0103",
    },
]

PROJECTS = [
    {
        "username": "client1",
        "title": "Radiomics pipeline audit",
        "category": ProjectBrief.CATEGORY_MEDICAL_IMAGING,
        "description": (
            "We need Tecvico to review our current radiomics extraction workflow "
            "and align it with IBSI 2.0 standards across PET/CT datasets.\n\n"
            "Goals: Standardize preprocessing, document gaps, and deliver a "
            "remediation plan."
        ),
        "budget_range": ProjectBrief.BUDGET_5K_15K,
        "desired_deadline": date(2026, 9, 30),
        "reference_links": "https://example.com/radiomics-spec\nhttps://example.com/sample-dataset",
        "status": ProjectBrief.STATUS_UNDER_REVIEW,
        "quote_text": "",
        "internal_notes": ["Client has 120-case retrospective cohort ready."],
    },
    {
        "username": "client1",
        "title": "Clinical trial dashboard",
        "category": ProjectBrief.CATEGORY_WEB,
        "description": (
            "Build a secure web dashboard for monitoring recruitment, imaging QC, "
            "and milestone completion across two active trials.\n\n"
            "Goals: Role-based views for coordinators and PI weekly status exports."
        ),
        "budget_range": ProjectBrief.BUDGET_15K_50K,
        "desired_deadline": date(2026, 11, 15),
        "reference_links": "https://example.com/wireframes",
        "status": ProjectBrief.STATUS_QUOTED,
        "quote_text": (
            "Phase 1 discovery and UX: $8,500\n"
            "Phase 2 build and QA: $22,000\n"
            "Estimated timeline: 10 weeks."
        ),
        "internal_notes": ["Needs SSO discussion on kickoff call."],
    },
    {
        "username": "sarah.research",
        "title": "Workflow automation for cohort exports",
        "category": ProjectBrief.CATEGORY_WORKFLOW,
        "description": (
            "Automate export of segmented lesions and feature tables from Tecvico "
            "into our downstream R analysis environment.\n\n"
            "Goals: One-click export with audit log and reproducible config files."
        ),
        "budget_range": ProjectBrief.BUDGET_5K_15K,
        "desired_deadline": date(2026, 8, 1),
        "reference_links": "",
        "status": ProjectBrief.STATUS_IN_PROGRESS,
        "quote_text": "Fixed fee $11,500 — delivery in 6 weeks with two revision rounds.",
        "internal_notes": ["Milestone 1 approved.", "Waiting on sample DICOM push."],
    },
    {
        "username": "sarah.research",
        "title": "Publication figure package",
        "category": ProjectBrief.CATEGORY_RESEARCH,
        "description": (
            "Prepare publication-ready figures and methods appendix for a radiomics "
            "paper.\n\n"
            "Goals: Journal-compliant figures, caption draft, and reproducibility "
            "checklist."
        ),
        "budget_range": ProjectBrief.BUDGET_UNDER_5K,
        "desired_deadline": date(2026, 7, 20),
        "reference_links": "https://example.com/journal-guidelines",
        "status": ProjectBrief.STATUS_DELIVERED,
        "quote_text": "",
        "internal_notes": ["Delivered v2 figures on June 12."],
    },
    {
        "username": "devteam",
        "title": "Multi-site data harmonization study",
        "category": ProjectBrief.CATEGORY_DATA,
        "description": (
            "Assess batch effects across three hospital sites and propose "
            "harmonization strategy before model training.\n\n"
            "Goals: Site effect report, recommended normalization approach, and "
            "pilot notebook."
        ),
        "budget_range": ProjectBrief.BUDGET_50K_PLUS,
        "desired_deadline": date(2027, 1, 31),
        "reference_links": "https://example.com/data-dictionary",
        "status": ProjectBrief.STATUS_SUBMITTED,
        "quote_text": "",
        "internal_notes": [],
    },
]


class Command(BaseCommand):
    help = "Seed demo client accounts and project briefs for the managed projects portal."

    def add_arguments(self, parser):
        parser.add_argument(
            "--flush",
            action="store_true",
            help="Delete seeded demo users and their project briefs before re-seeding.",
        )

    def handle(self, *args, **options):
        post_save.disconnect(handle_brief_notifications, sender=ProjectBrief)
        pre_save.disconnect(capture_previous_status, sender=ProjectBrief)
        try:
            with transaction.atomic():
                if options["flush"]:
                    self._flush()
                users = self._seed_clients()
                count = self._seed_projects(users)
        finally:
            post_save.connect(handle_brief_notifications, sender=ProjectBrief)
            pre_save.connect(capture_previous_status, sender=ProjectBrief)

        self.stdout.write(self.style.SUCCESS(f"Seeded {len(users)} clients and {count} project briefs."))
        self.stdout.write("Demo login: client1 / ClientDemo2026!")

    def _flush(self):
        User = get_user_model()
        usernames = [client["username"] for client in CLIENTS]
        users = User.objects.filter(username__in=usernames)
        ProjectBrief.objects.filter(client__in=users).delete()
        ClientProfile.objects.filter(user__in=users).delete()
        deleted, _ = users.delete()
        self.stdout.write(f"  Removed {deleted} demo user records")

    def _seed_clients(self):
        User = get_user_model()
        users = {}
        for client in CLIENTS:
            user, created = User.objects.get_or_create(
                username=client["username"],
                defaults={
                    "email": client["email"],
                    "first_name": client["first_name"],
                    "last_name": client["last_name"],
                },
            )
            user.email = client["email"]
            user.first_name = client["first_name"]
            user.last_name = client["last_name"]
            user.set_password(client["password"])
            user.save()

            ClientProfile.objects.update_or_create(
                user=user,
                defaults={
                    "company": client["company"],
                    "phone": client["phone"],
                },
            )
            action = "Created" if created else "Updated"
            self.stdout.write(f"  {action} client: {user.username}")
            users[user.username] = user
        return users

    def _seed_projects(self, users):
        admin = get_user_model().objects.filter(is_superuser=True).first()
        count = 0
        for project in PROJECTS:
            client = users[project["username"]]
            brief, created = ProjectBrief.objects.update_or_create(
                client=client,
                title=project["title"],
                defaults={
                    "category": project["category"],
                    "description": project["description"],
                    "budget_range": project["budget_range"],
                    "desired_deadline": project["desired_deadline"],
                    "reference_links": project["reference_links"],
                    "status": project["status"],
                    "quote_text": project["quote_text"],
                },
            )
            if created:
                count += 1
                action = "Created"
            else:
                action = "Updated"
            self.stdout.write(f"  {action} project: {brief.title}")

            if project["internal_notes"] and admin:
                for note in project["internal_notes"]:
                    ProjectInternalNote.objects.get_or_create(
                        brief=brief,
                        note=note,
                        defaults={"author": admin},
                    )
        return count
