from pydantic import BaseModel
from typing import Optional
from enum import Enum


class Role(str, Enum):
    sysadmin = "sysadmin"
    admin = "admin"
    editor = "editor"
    user = "user"


class MelodiesPermissions(BaseModel):
    view: bool = False
    add: bool = False
    delete: bool = False
    safe_edit: bool = False
    full_edit: bool = False
    archetype_access: bool = False
    settings_access: bool = False
    compose_access: bool = False


class DevicesPermissions(BaseModel):
    view: bool = False
    add: bool = False
    delete: bool = False
    safe_edit: bool = False
    edit_bells: bool = False
    edit_clock: bool = False
    edit_warranty: bool = False
    full_edit: bool = False
    control: bool = False


class AppUsersPermissions(BaseModel):
    view: bool = False
    add: bool = False
    delete: bool = False
    safe_edit: bool = False
    full_edit: bool = False


class IssuesNotesPermissions(BaseModel):
    view: bool = False
    add: bool = False
    delete: bool = False
    edit: bool = False


class MailPermissions(BaseModel):
    view: bool = False
    compose: bool = False
    reply: bool = False


class CrmPermissions(BaseModel):
    activity_log: bool = False


class CrmCustomersPermissions(BaseModel):
    full_access: bool = False
    overview: bool = False
    orders_view: bool = False
    orders_edit: bool = False
    quotations_view: bool = False
    quotations_edit: bool = False
    comms_view: bool = False
    comms_log: bool = False
    comms_edit: bool = False
    comms_compose: bool = False
    add: bool = False
    delete: bool = False
    files_view: bool = False
    files_edit: bool = False
    devices_view: bool = False
    devices_edit: bool = False


class CrmProductsPermissions(BaseModel):
    view: bool = False
    add: bool = False
    edit: bool = False


class MfgPermissions(BaseModel):
    view_inventory: bool = False
    edit: bool = False
    provision: bool = False
    firmware_view: bool = False
    firmware_edit: bool = False


class ApiReferencePermissions(BaseModel):
    access: bool = False


class MqttPermissions(BaseModel):
    access: bool = False


class StaffPermissions(BaseModel):
    melodies: MelodiesPermissions = MelodiesPermissions()
    devices: DevicesPermissions = DevicesPermissions()
    app_users: AppUsersPermissions = AppUsersPermissions()
    issues_notes: IssuesNotesPermissions = IssuesNotesPermissions()
    mail: MailPermissions = MailPermissions()
    crm: CrmPermissions = CrmPermissions()
    crm_customers: CrmCustomersPermissions = CrmCustomersPermissions()
    crm_products: CrmProductsPermissions = CrmProductsPermissions()
    mfg: MfgPermissions = MfgPermissions()
    api_reference: ApiReferencePermissions = ApiReferencePermissions()
    mqtt: MqttPermissions = MqttPermissions()


def default_permissions_for_role(role: str) -> Optional[dict]:
    if role in ("sysadmin", "admin"):
        return None  # Full access, permissions field not used

    if role == "editor":
        return {
            "melodies": {"view": True, "add": True, "delete": True, "safe_edit": True, "full_edit": True, "archetype_access": True, "settings_access": True, "compose_access": True},
            "devices": {"view": True, "add": True, "delete": True, "safe_edit": True, "edit_bells": True, "edit_clock": True, "edit_warranty": True, "full_edit": True, "control": True},
            "app_users": {"view": True, "add": True, "delete": True, "safe_edit": True, "full_edit": True},
            "issues_notes": {"view": True, "add": True, "delete": True, "edit": True},
            "mail": {"view": True, "compose": True, "reply": True},
            "crm": {"activity_log": True},
            "crm_customers": {"full_access": True, "overview": True, "orders_view": True, "orders_edit": True, "quotations_view": True, "quotations_edit": True, "comms_view": True, "comms_log": True, "comms_edit": True, "comms_compose": True, "add": True, "delete": True, "files_view": True, "files_edit": True, "devices_view": True, "devices_edit": True},
            "crm_products": {"view": True, "add": True, "edit": True},
            "mfg": {"view_inventory": True, "edit": True, "provision": True, "firmware_view": True, "firmware_edit": True},
            "api_reference": {"access": True},
            "mqtt": {"access": True},
        }

    # user role - view only
    return {
        "melodies": {"view": True, "add": False, "delete": False, "safe_edit": False, "full_edit": False, "archetype_access": False, "settings_access": False, "compose_access": False},
        "devices": {"view": True, "add": False, "delete": False, "safe_edit": False, "edit_bells": False, "edit_clock": False, "edit_warranty": False, "full_edit": False, "control": False},
        "app_users": {"view": True, "add": False, "delete": False, "safe_edit": False, "full_edit": False},
        "issues_notes": {"view": True, "add": False, "delete": False, "edit": False},
        "mail": {"view": True, "compose": False, "reply": False},
        "crm": {"activity_log": False},
        "crm_customers": {"full_access": False, "overview": True, "orders_view": True, "orders_edit": False, "quotations_view": True, "quotations_edit": False, "comms_view": True, "comms_log": False, "comms_edit": False, "comms_compose": False, "add": False, "delete": False, "files_view": True, "files_edit": False, "devices_view": True, "devices_edit": False},
        "crm_products": {"view": True, "add": False, "edit": False},
        "mfg": {"view_inventory": True, "edit": False, "provision": False, "firmware_view": True, "firmware_edit": False},
        "api_reference": {"access": False},
        "mqtt": {"access": False},
    }


class AdminUserInDB(BaseModel):
    uid: str
    email: str
    hashed_password: str
    name: str
    role: Role
    is_active: bool = True
    permissions: Optional[StaffPermissions] = None


class LoginRequest(BaseModel):
    email: str
    password: str


class TokenResponse(BaseModel):
    access_token: str
    token_type: str = "bearer"
    role: str
    name: str
    permissions: Optional[dict] = None


class TokenPayload(BaseModel):
    sub: str
    email: str
    role: str
    name: str
    exp: Optional[int] = None
