# Familiar - Self-Hosted AI Companion Platform
# Copyright (c) 2026 George Scott Foley
# ORCID: 0009-0006-4957-0540
# Email: Georgescottfoley@proton.me
# Licensed under the MIT License - see LICENSE file for details

"""Tests for Social Worker cases CRUD operations."""

from unittest.mock import patch

import pytest


@pytest.fixture
def tmp_data_dir(tmp_path):
    """Patch data dir to use temp directory."""
    with patch("familiar.dashboard.cases_crud._get_data_dir", return_value=tmp_path):
        yield tmp_path


class TestCaseCRUD:
    def test_create_case(self, tmp_data_dir):
        from familiar.dashboard.cases_crud import add_case, get_all_cases

        add_case({"name": "Jane Doe", "category": "housing", "priority": "high"})
        cases = get_all_cases()
        assert len(cases) == 1
        assert cases[0]["name"] == "Jane Doe"
        assert cases[0]["category"] == "housing"
        assert cases[0]["status"] == "intake"

    def test_update_case(self, tmp_data_dir):
        from familiar.dashboard.cases_crud import add_case, get_all_cases, update_case

        add_case({"name": "Jane Doe"})
        case_id = get_all_cases()[0]["id"]

        result = update_case({"id": case_id, "status": "active", "priority": "urgent"})
        assert result["status"] == "active"
        assert result["priority"] == "urgent"
        assert result["name"] == "Jane Doe"

    def test_update_case_not_found(self, tmp_data_dir):
        from familiar.dashboard.cases_crud import update_case

        result = update_case({"id": "nonexistent", "status": "active"})
        assert "error" in result

    def test_delete_case(self, tmp_data_dir):
        from familiar.dashboard.cases_crud import add_case, delete_case, get_all_cases

        add_case({"name": "Jane Doe"})
        case_id = get_all_cases()[0]["id"]

        result = delete_case(case_id)
        assert result["success"] is True
        assert len(get_all_cases()) == 0

    def test_add_interaction(self, tmp_data_dir):
        from familiar.dashboard.cases_crud import add_case, add_case_interaction, get_all_cases

        add_case({"name": "Jane Doe"})
        case_id = get_all_cases()[0]["id"]

        result = add_case_interaction(
            {
                "case_id": case_id,
                "type": "phone_call",
                "description": "Follow-up call",
            }
        )
        # 1 intake + 1 phone_call = 2
        assert len(result["interactions"]) == 2
        assert result["interactions"][-1]["type"] == "phone_call"


class TestResourceCRUD:
    def test_create_resource(self, tmp_data_dir):
        from familiar.dashboard.cases_crud import add_resource, get_all_resources

        add_resource({"name": "City Food Bank", "category": "food", "phone": "555-1234"})
        resources = get_all_resources()
        assert len(resources) == 1
        assert resources[0]["name"] == "City Food Bank"

    def test_update_resource(self, tmp_data_dir):
        from familiar.dashboard.cases_crud import add_resource, get_all_resources, update_resource

        add_resource({"name": "City Food Bank"})
        res_id = get_all_resources()[0]["id"]

        result = update_resource({"id": res_id, "phone": "555-9999"})
        assert result["phone"] == "555-9999"

    def test_delete_resource(self, tmp_data_dir):
        from familiar.dashboard.cases_crud import add_resource, delete_resource, get_all_resources

        add_resource({"name": "Test"})
        res_id = get_all_resources()[0]["id"]

        result = delete_resource(res_id)
        assert result["success"] is True
        assert len(get_all_resources()) == 0


class TestCaseNoteCRUD:
    def test_create_note(self, tmp_data_dir):
        from familiar.dashboard.cases_crud import add_case_note, get_all_case_notes

        add_case_note({"content": "Initial assessment", "category": "assessment"})
        notes = get_all_case_notes()
        assert len(notes) == 1
        assert notes[0]["content"] == "Initial assessment"

    def test_delete_note(self, tmp_data_dir):
        from familiar.dashboard.cases_crud import (
            add_case_note,
            delete_case_note,
            get_all_case_notes,
        )

        add_case_note({"content": "Test"})
        note_id = get_all_case_notes()[0]["id"]

        result = delete_case_note(note_id)
        assert result["success"] is True
        assert len(get_all_case_notes()) == 0


class TestHMISFields:
    def test_new_case_has_hmis_fields(self, tmp_data_dir):
        from familiar.dashboard.cases_crud import add_case, get_all_cases

        add_case({"name": "Jane Doe", "dob": "1990-05-15", "gender": "female"})
        cases = get_all_cases()
        c = cases[0]
        assert c["dob"] == "1990-05-15"
        assert c["gender"] == "female"
        assert c["veteran_status"] == ""
        assert c["assessments"] == []
        assert c["safety_plan"] == {}
        assert c["mandatory_report_flags"] == []

    def test_backfill_legacy_case(self, tmp_data_dir):
        """Legacy cases without HMIS fields get backfilled on load."""
        import json

        data = {
            "cases": [
                {
                    "id": "leg1",
                    "name": "Old Case",
                    "category": "general",
                    "status": "active",
                    "priority": "normal",
                    "assigned_to": "",
                    "phone": "",
                    "email": "",
                    "address": "",
                    "notes": "",
                    "created_at": "2025-01-01T00:00:00",
                    "updated_at": "2025-01-01T00:00:00",
                    "follow_up_date": "",
                    "interactions": [],
                }
            ],
            "resources": [],
            "notes": [],
            "crisis_log": [],
        }
        with open(tmp_data_dir / "cases.json", "w") as f:
            json.dump(data, f)

        from familiar.dashboard.cases_crud import get_all_cases

        cases = get_all_cases()
        c = cases[0]
        assert c["dob"] == ""
        assert c["race"] == []
        assert c["assessments"] == []
        assert c["safety_plan"] == {}


class TestClinicalAssessments:
    def test_add_assessment(self, tmp_data_dir):
        from familiar.dashboard.cases_crud import add_assessment, add_case, get_all_cases

        add_case({"name": "Jane Doe"})
        case_id = get_all_cases()[0]["id"]

        result = add_assessment(
            case_id,
            {
                "tool": "PHQ-9",
                "score": 14,
                "severity": "moderate",
            },
        )
        assert result["tool"] == "PHQ-9"
        assert result["score"] == 14

        cases = get_all_cases()
        assert len(cases[0]["assessments"]) == 1

    def test_add_cssrs_assessment(self, tmp_data_dir):
        from familiar.dashboard.cases_crud import add_assessment, add_case, get_all_cases

        add_case({"name": "Jane"})
        case_id = get_all_cases()[0]["id"]

        result = add_assessment(
            case_id,
            {
                "tool": "C-SSRS",
                "risk_level": "moderate",
                "ideation": True,
                "plan": False,
                "intent": False,
            },
        )
        assert result["tool"] == "C-SSRS"
        assert result["ideation"] is True

    def test_assessment_case_not_found(self, tmp_data_dir):
        from familiar.dashboard.cases_crud import add_assessment

        result = add_assessment("bad_id", {"tool": "PHQ-9", "score": 5})
        assert "error" in result


class TestSafetyPlan:
    def test_save_safety_plan(self, tmp_data_dir):
        from familiar.dashboard.cases_crud import add_case, get_all_cases, save_safety_plan

        add_case({"name": "Jane"})
        case_id = get_all_cases()[0]["id"]

        result = save_safety_plan(
            case_id,
            {
                "warning_signs": ["Feeling hopeless", "Isolating"],
                "coping_strategies": ["Go for a walk", "Call a friend"],
                "professional_contacts": [{"name": "Dr. Smith", "phone": "555-1234"}],
                "reasons_for_living": ["My children", "My dog"],
            },
        )
        assert len(result["warning_signs"]) == 2
        assert len(result["coping_strategies"]) == 2
        assert result["last_reviewed"] != ""


class TestMandatoryReporting:
    def test_add_mandatory_report(self, tmp_data_dir):
        from familiar.dashboard.cases_crud import add_case, add_mandatory_report, get_all_cases

        add_case({"name": "Jane"})
        case_id = get_all_cases()[0]["id"]

        result = add_mandatory_report(
            case_id,
            {
                "type": "child_abuse",
                "reported_to": "CPS",
                "report_id": "CPS-2026-001",
            },
        )
        assert result["type"] == "child_abuse"
        assert result["reported_to"] == "CPS"

        cases = get_all_cases()
        assert len(cases[0]["mandatory_report_flags"]) == 1


class TestCrisisLogCRUD:
    def test_create_crisis(self, tmp_data_dir):
        from familiar.dashboard.cases_crud import add_crisis_event, get_all_crisis_events

        add_crisis_event({"summary": "Client in distress", "severity": "high"})
        events = get_all_crisis_events()
        assert len(events) == 1
        assert events[0]["severity"] == "high"

    def test_delete_crisis(self, tmp_data_dir):
        from familiar.dashboard.cases_crud import (
            add_crisis_event,
            delete_crisis_event,
            get_all_crisis_events,
        )

        add_crisis_event({"summary": "Test"})
        event_id = get_all_crisis_events()[0]["id"]

        result = delete_crisis_event(event_id)
        assert result["success"] is True
        assert len(get_all_crisis_events()) == 0
