import os
import unittest

os.environ.setdefault("JWT_SECRET", "test-jwt-secret-value-with-32-chars")
os.environ.setdefault("DB_NAME", "test.db")

from fastapi import FastAPI
from fastapi.testclient import TestClient
from sqlalchemy import create_engine
from sqlalchemy.orm import Session, sessionmaker
from sqlalchemy.pool import StaticPool

from app.api.auth import router as auth_router
from app.core.database import Base, get_db
from app.core.models import Tenant, TenantStatus, User, UserRole, UserStatus
from app.core.security import hash_password


class TenantAuthContractTests(unittest.TestCase):
    def setUp(self):
        self.engine = create_engine("sqlite://", connect_args={"check_same_thread": False}, poolclass=StaticPool)
        self.SessionLocal = sessionmaker(bind=self.engine)
        Base.metadata.create_all(self.engine)
        self.app = FastAPI()
        self.app.include_router(auth_router)

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

        self.app.dependency_overrides[get_db] = override_get_db
        self.addCleanup(self.app.dependency_overrides.clear)
        self.client = TestClient(self.app)

    def _seed_tenant(self, company_code="alpha", name="Alpha Co"):
        with Session(self.engine) as s:
            t = Tenant(company_code=company_code, name=name, status=TenantStatus.active)
            s.add(t)
            s.commit()
            s.refresh(t)
            return t

    def _seed_user(self, tenant_id, username="admin", password="secret123456"):
        with Session(self.engine) as s:
            u = User(tenant_id=tenant_id, username=username, password_hash=hash_password(password), role=UserRole.admin, status=UserStatus.active)
            s.add(u)
            s.commit()
            s.refresh(u)
            return u

    def test_login_requires_company_code(self):
        response = self.client.post("/api/auth/login", json={"username": "admin", "password": "secret"})
        assert response.status_code == 422

    def test_login_with_valid_company_code(self):
        t = self._seed_tenant()
        self._seed_user(t.id)
        response = self.client.post("/api/auth/login", json={"company_code": "alpha", "username": "admin", "password": "secret123456"})
        assert response.status_code == 200
        data = response.json()
        assert data["user"]["tenant"]["company_code"] == "alpha"

    def test_login_wrong_company_code(self):
        t = self._seed_tenant()
        self._seed_user(t.id)
        response = self.client.post("/api/auth/login", json={"company_code": "wrong", "username": "admin", "password": "secret123456"})
        assert response.status_code == 401

    def test_same_username_different_tenants(self):
        t1 = self._seed_tenant("alpha", "Alpha")
        t2 = self._seed_tenant("beta", "Beta")
        self._seed_user(t1.id, "admin", "alpha-password1")
        self._seed_user(t2.id, "admin", "beta-password12")
        r1 = self.client.post("/api/auth/login", json={"company_code": "alpha", "username": "admin", "password": "alpha-password1"})
        r2 = self.client.post("/api/auth/login", json={"company_code": "beta", "username": "admin", "password": "beta-password12"})
        assert r1.status_code == 200
        assert r2.status_code == 200
        assert r1.json()["user"]["tenant"]["company_code"] == "alpha"
        assert r2.json()["user"]["tenant"]["company_code"] == "beta"


if __name__ == "__main__":
    unittest.main()
