from sqlalchemy.orm import Session
from sqlalchemy.exc import IntegrityError
from domain.users import User
from application.ports.user_repository import UserRepository
from infrastructure.adapters.persistence.db import SessionLocal
from infrastructure.adapters.persistence.models import UserModel
from application.exceptions import UserAlreadyExists

class SqlUserRepository(UserRepository):
    def __init__(self):
        self.db: Session = SessionLocal()

    def save(self, user: User):
        model = UserModel(
            name= user.name,
            email=user.email,
            phone=user.phone
            )
        
        self.db.add(model)

        try:
            self.db.commit()
        except IntegrityError:
            self.db.rollback()
            raise UserAlreadyExists("A user with the same phone number or name does already exist.")
        

        self.db.refresh(model)

        return User(
            user_id = model.user_id,
            name  = model.name,
            email = model.email,
            phone = model.phone
            )
    
    def viewAll(self) -> list[User]:
        models = self.db.query(UserModel).all()

        return [
            User(
                user_id=model.user_id,
                name  = model.name,
                email = model.email,
                phone = model.phone
            ) for model in models
        ]
    
    def viewById(self, user_id: int) -> User | None:
        model = self.db.query(UserModel).filter(UserModel.user_id == user_id).first()

        if not model:
            return None
        
        return User(
            user_id=model.user_id,
            name  = model.name,
            email = model.email,
            phone = model.phone
        )