import os
import copy
import json
import pytest
from unittest.mock import MagicMock
from fastapi.testclient import TestClient
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

os.environ.setdefault("DATABASE_URL", os.environ.get("DATABASE_URL", ""))

from app.database import Base, get_db
from app.main import app
from app.models import SiteProfile, ProjectContext, GlobalContext, Domain, AuraUser, AppSettings

TEST_DATABASE_URL = os.environ.get("DATABASE_URL")

engine = create_engine(TEST_DATABASE_URL, pool_pre_ping=True)
TestingSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)


def override_get_db():
    db = TestingSessionLocal()
    try:
        yield db
    finally:
        db.close()


app.dependency_overrides[get_db] = override_get_db


def _ensure_test_user():
    db = TestingSessionLocal()
    try:
        user = db.query(AuraUser).filter(AuraUser.username == "testadmin").first()
        if not user:
            user = AuraUser(username="testadmin", is_admin=True)
            user.set_password("testpass")
            db.add(user)
        setting = db.query(AppSettings).filter(AppSettings.key == "login_enabled").first()
        if not setting:
            setting = AppSettings(key="login_enabled", value="true")
            db.add(setting)
        else:
            setting.value = "true"
        db.commit()
    finally:
        db.close()

_ensure_test_user()


@pytest.fixture(scope="session")
def client():
    with TestClient(app) as c:
        c.post("/login", data={"username": "testadmin", "password": "testpass"})
        yield c


@pytest.fixture
def unauthed_client():
    with TestClient(app) as c:
        yield c


@pytest.fixture
def db_session():
    db = TestingSessionLocal()
    try:
        yield db
    finally:
        db.close()


@pytest.fixture
def dev_token():
    return "N5G4K8fWLY9MrapEkZnw_g"


SAMPLE_ANALYSIS = {
    "domain": "test.com",
    "keywords": ["test", "example"],
    "interpretations": ["A testing domain"],
    "domain_summary": "A domain for testing purposes",
    "niches": [
        {
            "name": "Software Testing",
            "description": "Tools and resources for software testing",
            "score": 8,
            "monetization_model": "affiliate",
            "target_audience": "Developers, QA Engineers",
            "time_to_revenue": "medium",
            "valuation_band": "5000-20000",
            "affiliate_programs": ["TestRail", "BrowserStack"],
            "requires_inventory": False,
            "synopsis": "A niche focused on software testing."
        }
    ]
}

SAMPLE_BRAND = {
    "options": [
        {"name": "TestBrand", "tagline": "Quality First"},
        {"name": "TestPro", "tagline": "Professional Testing"},
        {"name": "QualityHub", "tagline": "Your Testing Partner"}
    ],
    "recommended": 0,
    "color_primary": "#4F46E5",
    "color_secondary": "#7C3AED",
    "color_accent": "#06B6D4",
    "industry_context": "Software testing and quality assurance"
}


@pytest.fixture
def sample_analysis():
    return copy.deepcopy(SAMPLE_ANALYSIS)


@pytest.fixture
def sample_brand():
    return copy.deepcopy(SAMPLE_BRAND)


@pytest.fixture
def sample_niche():
    return copy.deepcopy(SAMPLE_ANALYSIS["niches"][0])


@pytest.fixture
def mock_openai_client():
    mock_client = MagicMock()
    mock_response = MagicMock()
    mock_choice = MagicMock()
    mock_choice.message.content = '{"test": true}'
    mock_response.choices = [mock_choice]
    mock_client.chat.completions.create.return_value = mock_response
    return mock_client


@pytest.fixture
def mock_llm_json_response():
    def _factory(data: dict):
        return json.dumps(data)
    return _factory
