import random
import string
import uuid
from datetime import datetime, timezone
from controller.mail_helper import MailHelper
from MongoDBConnection import MONGO_URI, DB_NAME
from pymongo import MongoClient
from bson.objectid import ObjectId

client = MongoClient(MONGO_URI)
db = client[DB_NAME]
collection = db["users"]

class StaffModel:
    @staticmethod
    def generate_random_password(length=8):
        characters = string.ascii_letters + string.digits
        return ''.join(random.choice(characters) for _ in range(length))

    @classmethod
    def create_staff(cls, name: str, email: str, permissions: list):
        raw_password = cls.generate_random_password(8)
        staff_id = str(uuid.uuid4())
        created_at = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%S.000Z")
        
        mail_data = {
            "username": name,
            "password": raw_password,
            "note": "Đây là tài khoản Staff của bạn. Hãy đổi mật khẩu sau khi đăng nhập."
        }

        new_staff = {
            "id": staff_id,
            "name": name,
            "email": email,
            "password": raw_password,
            "role": "staff",
            "status": "active",
            "permissions": permissions,
            "createdAt": created_at
        }

        MailHelper.send_new_password_email(email, mail_data) 
        existing_user = collection.find_one({"email": email})
        if existing_user:
            # Nếu tồn tại, ném ra lỗi để FastAPI trả về cho Frontend
            raise Exception("Email đã tồn tại trong hệ thống!")
        collection.insert_one(new_staff) 
        if "_id" in new_staff:
            new_staff["_id"] = str(new_staff["_id"])
        return new_staff
    
    @staticmethod
    def check_access(user_permissions: list, required_permission: str):
        """
        Kiểm tra xem quyền yêu cầu có nằm trong danh sách quyền của user hay không.
        Đây là logic động, thay thế cho logic chặn cứng "is_authorized" cũ.
        """
        if "admin" in user_permissions: # Giả định admin có full quyền
            return True
            
        return required_permission in user_permissions
    
    @classmethod
    def change_password(cls, staff_id: str, old_password: str, new_password: str):
        # 1. Tìm nhân viên bằng ObjectId (Vì lúc login ta trả về _id của MongoDB)
        try:
            query = {"_id": ObjectId(staff_id), "role": "staff"}
        except Exception:
            # Phòng hờ trường hợp staff_id là mã UUID dạng chuỗi
            query = {"id": staff_id, "role": "staff"}
            
        staff = collection.find_one(query)
        
        if not staff:
            return False, "Tài khoản không tồn tại trên hệ thống!"
        
        # 2. Kiểm tra mật khẩu cũ
        if staff.get("password") != old_password:
            return False, "Mật khẩu hiện tại không chính xác!"
            
        # 3. Cập nhật mật khẩu mới
        collection.update_one(query, {"$set": {"password": new_password}})
        return True, "Đổi mật khẩu thành công!"
    
    @classmethod
    def update_staff(cls, staff_id: str, email: str, status: str, permissions: list):
        try:
            query = {"_id": ObjectId(staff_id)}
        except:
            query = {"id": staff_id}
            
        result = collection.update_one(
            query,
            {"$set": {
                "email": email,
                "status": status,
                "permissions": permissions
            }}
        )
        return True, "Cập nhật nhân viên thành công!"

    @classmethod
    def admin_reset_password(cls, staff_id: str):
        try:
            query = {"_id": ObjectId(staff_id)}
        except:
            query = {"id": staff_id}
            
        staff = collection.find_one(query)
        if not staff:
            return False, "Không tìm thấy nhân viên!"
            
        # 1. Tạo mật khẩu ngẫu nhiên mới
        raw_password = cls.generate_random_password(8)
        
        # 2. Cập nhật vào DB
        collection.update_one(query, {"$set": {"password": raw_password}})
        
        # 3. Gửi Email cho nhân viên
        mail_data = {
            "username": staff.get("name", "Staff"),
            "password": raw_password,
            "note": "Mật khẩu của bạn vừa được Admin đặt lại. Hãy đổi mật khẩu ngay sau khi đăng nhập."
        }
        try:
            MailHelper.send_new_password_email(staff["email"], mail_data)
        except Exception as e:
            print(f"Lỗi gửi mail: {e}")
            
        return True, f"Đã tạo mật khẩu mới và gửi email tới {staff['email']}!"