"""Phase 6.1 model / validation / audit / service tests."""
from __future__ import annotations

from decimal import Decimal

import pytest
from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker

from app.core.database import engine
from app.models.types import CustomFieldType, LeadStatus
from app.schemas.foundation import (
    AttachmentCreate,
    LeadCreate,
    NoteCreate,
)
from app.services.audit_service import AuditService
from app.services.lead_service import LeadService
from app.services.supporting_services import AttachmentService, NoteService
from app.tests.conftest import TENANT_A
from app.validators import (
    validate_custom_field_value,
    validate_email,
    validate_lead_status,
    validate_owner,
    validate_phone,
)
from shared.exceptions import AppError
from shared.security import CurrentUser


def test_email_validation():
    assert validate_email("A@B.com") == "a@b.com"
    with pytest.raises(AppError):
        validate_email("bad-email")


def test_phone_validation():
    assert validate_phone("+98 912 123 4567") is not None
    with pytest.raises(AppError):
        validate_phone("12")


def test_owner_required():
    assert validate_owner("u-1") == "u-1"
    with pytest.raises(AppError):
        validate_owner("")


def test_lead_status_validation():
    assert validate_lead_status("qualified") == LeadStatus.QUALIFIED
    with pytest.raises(AppError):
        validate_lead_status("nope")


def test_custom_field_select_validation():
    validate_custom_field_value(
        field_type=CustomFieldType.SELECT,
        is_required=True,
        options=["a", "b"],
        value_text="a",
    )
    with pytest.raises(AppError):
        validate_custom_field_value(
            field_type=CustomFieldType.SELECT,
            is_required=True,
            options=["a", "b"],
            value_text="z",
        )


@pytest.mark.asyncio
async def test_lead_service_and_audit(db_setup):
    Session = async_sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
    async with Session() as session:
        svc = LeadService(session)
        actor = CurrentUser(user_id="actor-1", username="actor", roles=["tenant_admin"])
        lead = await svc.create(
            TENANT_A,
            LeadCreate(
                first_name="Nima",
                last_name="Ahmadi",
                email="nima@example.com",
                owner_user_id="owner-1",
                estimated_value=Decimal("1000"),
            ),
            actor=actor,
        )
        assert lead.lead_number
        assert lead.full_name == "Nima Ahmadi"
        audits = await AuditService(session).list_for_entity(TENANT_A, "lead", lead.id)
        assert any(a.action.value == "create" for a in audits)

        note = await NoteService(session).create(
            TENANT_A,
            NoteCreate(entity_type="lead", entity_id=lead.id, body="hello"),
            actor=actor,
        )
        assert note.version == 1

        att = await AttachmentService(session).create(
            TENANT_A,
            AttachmentCreate(
                entity_type="lead",
                entity_id=lead.id,
                file_storage_id="file-1",
                file_name="a.pdf",
            ),
            actor=actor,
        )
        assert att.file_storage_id == "file-1"
