from typing import List
from fastapi import HTTPException
from sqlalchemy.orm import Session
from app.api.admin.schemas import AdminCreate, AdminResponse, AdminUpdate, ChangePasswordRequest, UserResponse
from app.models.main.admin import AdminBase, TblAdmin
from app.models.main.users import TblUsers
from app.utils.schemas_utils import CustomResponse

class AdminService:
    def __init__(self, db: Session, token: dict):
        self.db = db
        self.token = token

    async def create_admin(self, request: AdminCreate):
        created_admin = TblAdmin(**request.dict())
        self.db.add(created_admin)
        self.db.flush()
        admin_id = created_admin.admin_id
        user_schema = UserResponse.model_validate(request)
        user_schema = user_schema.model_copy(update={"entity_id": admin_id, "password": request.pass_word})
        created_user = TblUsers(**user_schema.model_dump())
        self.db.add(created_user)
        self.db.commit()
        self.db.refresh(created_admin)
        return CustomResponse(status="1", message="Admin created successfully")

    async def get_admin_profile(self):
        admin_id = self.token.get("admin_id")
        if not admin_id:
            return CustomResponse(status="-1", message="Invalid token: admin_id missing")
        admin_profile = self.db.query(TblAdmin).filter(TblAdmin.admin_id == admin_id).first()
        if not admin_profile:
            return CustomResponse(status="-1", message="No admin data found")
        return CustomResponse(
            status="1",
            message="Admin Profile",
            data=AdminResponse.model_validate(admin_profile)
        )
    
    async def get_all_admins(self) -> List[AdminBase]:
        results = self.db.query(TblAdmin).all()
        return [AdminBase.model_validate(r) for r in results]

    async def change_password(self, request: ChangePasswordRequest):
        admin = TblAdmin.get_id(request.admin_id, self.db)
        if not admin:
            raise HTTPException(status_code=404, detail="Admin not found")
        if admin.pass_word != request.old_password:
            raise HTTPException(status_code=400, detail="Old password is incorrect")
        if request.new_password != request.confirm_password:
            raise HTTPException(status_code=400, detail="New password and confirm password do not match")
        admin.pass_word = request.new_password
        self.db.add(admin)
        user = self.db.query(TblUsers).filter(TblUsers.user_name == admin.user_name).first()
        if user:
            user.password = request.new_password
            self.db.add(user)
        self.db.commit()
        self.db.refresh(admin)
        return CustomResponse(status="1", message="Password changed successfully")
    
    async def update_admin(self, request: AdminUpdate):
        admin = AdminBase.model_validate(request)
        if admin.admin_id is None:
            raise HTTPException(status_code=404, detail="admin not found")
        updated_admin = TblAdmin.update(admin.admin_id, admin, self.db)
        if not updated_admin:
            raise HTTPException(status_code=404, detail="admin not found")
        user = (self.db.query(TblUsers).filter(TblUsers.entity_id == admin.admin_id, TblUsers.role_id == admin.role_id).first())
        if not user:
            raise HTTPException(status_code=404, detail="user not found for this admin")
        if admin.user_name is not None:
            user.user_name = admin.user_name
        if admin.pass_word is not None:
            user.password = admin.pass_word
        if admin.role_id is not None:
            user.role_id = admin.role_id
        if admin.company_id is not None:
            user.entity_id = admin.company_id
        self.db.add(user)
        self.db.commit()
        return CustomResponse(status="1", message="admin & user updated successfully")
