from dataclasses import dataclass

from django.contrib.auth import get_user_model
from django.contrib.auth.models import Group
from django.db import transaction
from django.db.models import Q
from . import models as basic_models

User = get_user_model()


class CustomerVisibilityService:
    @staticmethod
    def filter_customers_for_employee(customer_queryset, user):
        """
        过滤客户查询集，使其仅包含对指定员工可见的客户。
        """

        if user.is_superuser:
            return customer_queryset

        emp = getattr(user, 'employee', None)
        if emp is None:
            return customer_queryset.none()

        print(f'Filtering customers for employee: {emp.id}')
        # 员工创建的客户可见 + 员工被设置为可见员工的客户可见
        visibility_filter = Q(created_by=emp) | Q(visible_employees=emp)
        return customer_queryset.filter(visibility_filter).distinct()

    @staticmethod
    def is_customer_visible_to_employee(customer, user):
        """
        检查特定客户是否对指定员工可见。
        """

        if user.is_superuser:
            return True

        emp = getattr(user, 'employee', None)
        if emp is None:
            return False

        if customer.created_by == emp:
            return True

        if emp in customer.visible_employees.all():
            return True

        return False


class DataVisibilityService:
    @staticmethod
    def is_product_visible_to_employee(product_id: int, user):
        """
        检查特定产品是否对指定员工可见。
        """

        if user.is_superuser:
            return True

        emp: basic_models.Employee = getattr(user, 'employee', None)
        if emp is None:
            return False

        return basic_models.Product.objects.filter(id=product_id).filter(merchant=emp.merchant).exists()

    @staticmethod
    def is_warehouse_visible_to_employee(warehouse_id: int, user):
        """
        检查特定仓库是否对指定员工可见。
        """

        if user.is_superuser:
            return True

        emp: basic_models.Employee = getattr(user, 'employee', None)
        if emp is None:
            return False

        return basic_models.WareHouse.objects.filter(id=warehouse_id).filter(merchant=emp.merchant).exists()


class MerchantSettingService:
    @staticmethod
    def get_setting(merchant: basic_models.Merchant, key: basic_models.MerchantSettingKeyEnum):
        return basic_models.MerchantSetting.objects.get(merchant=merchant, key=key)


@dataclass
class QuickCreateEmployeeUserResult:
    user: object
    employee: basic_models.Employee
    role_id: int | None

    def to_dict(self) -> dict:
        return {
            "user": {
                "id": self.user.id,
                "username": self.user.username,
                "display_name": self.employee.name,
                "role_id": self.role_id,
            },
            "employee": {
                "id": self.employee.id,
                "name": self.employee.name,
                "status": self.employee.status,
                "merchant": self.employee.merchant_id,
            },
        }


class EmployeeUserProvisioningService:
    @staticmethod
    def quick_create_employee_user(
        *,
        username: str,
        password: str,
        display_name: str,
        merchant_id: int,
        email: str | None = None,
        mobile: str | None = None,
        area: str | None = None,
        description: str | None = None,
        status: int | None = None,
        role_id: int | None = None,
    ) -> QuickCreateEmployeeUserResult:
        username = (username or "").strip()
        if not username:
            raise ValueError("用户名不能为空")
        if User.objects.filter(username=username).exists():
            raise ValueError("用户名已存在")

        merchant = basic_models.Merchant.objects.filter(id=merchant_id).first()
        if merchant is None:
            raise ValueError("商户不存在")

        group = None
        if role_id is not None:
            group = Group.objects.filter(id=role_id).first()
            if group is None:
                raise ValueError("角色不存在")

        status_value = status or basic_models.EmployeeStatusEnum.ACTIVE

        with transaction.atomic():
            user = User.objects.create_user(
                username=username,
                password=password,
                email=(email or "").strip(),
            )
            user.first_name = display_name
            user.save(update_fields=["first_name"])

            if group is not None:
                user.groups.add(group)

            employee = basic_models.Employee.objects.create(
                merchant=merchant,
                sys_user=user,
                name=display_name,
                mobile=(mobile or "").strip(),
                area=(area or "").strip(),
                description=(description or "").strip(),
                status=status_value,
            )

        return QuickCreateEmployeeUserResult(
            user=user,
            employee=employee,
            role_id=group.id if group is not None else None,
        )
