"""Regression: AI-created invoice drafts must compute subtotal/tax/total.

Reproduces the autoflush=False bug where _create_invoice_draft queried the
freshly-added items before flushing, summing an empty set into 0 totals.
"""
import os
import sys
import unittest
from datetime import date
from decimal import Decimal
from pathlib import Path

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

ROOT = Path(__file__).resolve().parents[2]
BACKEND_ROOT = ROOT / "backend"
if str(BACKEND_ROOT) not in sys.path:
    sys.path.insert(0, str(BACKEND_ROOT))

# Set env vars before importing app.* so the real modules load without
# hitting their module-level guards (JWT_SECRET check, mysql fallback).
os.environ.setdefault("JWT_SECRET", "test-jwt-secret-value-with-32-chars")
os.environ.setdefault("DB_NAME", "test.db")

from app.api.ai import _create_invoice_draft
from app.core.database import Base
from app.core.models import Customer, Tenant


class AiInvoiceDraftTotalsTests(unittest.TestCase):
    def make_session(self):
        engine = create_engine("sqlite:///:memory:")
        Base.metadata.create_all(engine)
        # autoflush=False matches production SessionLocal — required to catch the bug.
        db = sessionmaker(autocommit=False, autoflush=False, bind=engine)()
        db.add(Tenant(id=1, company_code="test", name="Test"))
        db.commit()
        return db

    def test_draft_totals_are_computed(self):
        db = self.make_session()
        db.add(Customer(tenant_id=1, name="FIELD HOMES LIMITED", email="fh@example.com"))
        db.commit()

        reply, action, invoice_id = _create_invoice_draft(
            db,
            {
                "customer_name": "FIELD HOMES",
                "items": [
                    {"description": "Secondary Development", "quantity": 1,
                     "unit_price": 1500, "tax_rate": 0.15},
                ],
            },
            tenant_id=1,
        )

        self.assertEqual(action, "create_draft")
        from app.core.models import Invoice
        invoice = db.get(Invoice, invoice_id)
        self.assertEqual(invoice.subtotal, Decimal("1500.00"))
        self.assertEqual(invoice.total_tax, Decimal("225.00"))
        self.assertEqual(invoice.total_amount, Decimal("1725.00"))

    def test_missing_date_defaults_to_today(self):
        db = self.make_session()
        db.add(Customer(tenant_id=1, name="FIELD HOMES LIMITED", email="fh@example.com"))
        db.commit()

        _, _, invoice_id = _create_invoice_draft(
            db,
            {
                "customer_name": "FIELD HOMES",
                "invoice_date": "",  # AI emitted an empty string
                "due_date": "not-a-date",  # AI hallucinated garbage
                "items": [{"description": "x", "quantity": 1, "unit_price": 10}],
            },
            tenant_id=1,
        )

        from app.core.models import Invoice
        invoice = db.get(Invoice, invoice_id)
        self.assertEqual(invoice.invoice_date, date.today())
        self.assertIsNone(invoice.due_date)

    def test_draft_uses_configured_default_currency(self):
        db = self.make_session()
        db.add(Customer(tenant_id=1, name="FIELD HOMES LIMITED", email="fh@example.com"))
        from app.core.models import SystemConfig
        db.add(SystemConfig(tenant_id=1, key_name="default_currency", key_value="$"))
        db.commit()

        _, _, invoice_id = _create_invoice_draft(
            db,
            {
                "customer_name": "FIELD HOMES",
                "items": [{"description": "x", "quantity": 1, "unit_price": 10}],
            },
            tenant_id=1,
        )

        from app.core.models import Invoice
        self.assertEqual(db.get(Invoice, invoice_id).currency, "$")


if __name__ == "__main__":
    unittest.main()
