"""
Team / RBAC Pydantic schemas — PRD-008 RBAC Multi-User Merchant Accounts.
"""

from __future__ import annotations

from datetime import datetime
from typing import List, Optional

from pydantic import EmailStr, Field, ConfigDict

from src.apps.base.schemas.common import BaseSchema


# ─── Permission ───────────────────────────────────────────────────────────────


class PermissionSchema(BaseSchema):
    model_config = ConfigDict(from_attributes=True)

    id: int = Field(..., description="Permission ID")
    module: str = Field(..., description="Module name")
    submodule: Optional[str] = Field(None, description="Submodule name")
    operation: str = Field(..., description="Operation name")
    slug: str = Field(..., description="Permission slug, e.g. transactions:refund")
    operation_label: Optional[str] = Field(None, description="Human-readable label")
    display_order: Optional[int] = Field(None, description="Sort order for UI")


# ─── Role ─────────────────────────────────────────────────────────────────────


class RoleMinimalSchema(BaseSchema):
    model_config = ConfigDict(from_attributes=True)

    id: int
    label: Optional[str] = None
    slug: Optional[str] = None
    role_rank: int = 1


class RoleSchema(BaseSchema):
    model_config = ConfigDict(from_attributes=True)

    id: int
    label: Optional[str] = None
    slug: Optional[str] = None
    is_system: bool = False
    is_default: bool = False
    role_rank: int = 1
    description: Optional[str] = None
    permissions: List[PermissionSchema] = Field(default_factory=list)
    member_count: Optional[int] = None


# ─── Team members ─────────────────────────────────────────────────────────────


class TeamMemberSchema(BaseSchema):
    model_config = ConfigDict(from_attributes=True)

    user_id: int
    email: str
    first_name: Optional[str] = None
    last_name: Optional[str] = None
    full_name: Optional[str] = None
    role: RoleSchema
    is_owner: bool = False
    joined_at: datetime


# ─── Invites ──────────────────────────────────────────────────────────────────


class InviteSchema(BaseSchema):
    model_config = ConfigDict(from_attributes=True)

    id: int
    email: str
    role: RoleSchema
    invited_by_name: str
    expires_at: datetime
    created_at: datetime


class InviteInfoResponse(BaseSchema):
    merchant_name: str
    merchant_logo_url: Optional[str] = None
    role_name: str
    email: str
    expires_at: datetime


class AcceptInviteResponse(BaseSchema):
    access_token: str
    refresh_token: str
    token_type: str = "bearer"
    expires_at: str
    user: dict


# ─── My permissions ───────────────────────────────────────────────────────────


class MyPermissionsResponse(BaseSchema):
    permissions: List[str] = Field(default_factory=list)
    role: Optional[RoleMinimalSchema] = None


# ─── Request bodies ───────────────────────────────────────────────────────────


class InviteUserRequest(BaseSchema):
    email: EmailStr = Field(..., description="Email address to invite")
    role_id: int = Field(..., description="Role to assign to the invited user")


class AcceptInviteRequest(BaseSchema):
    token: str = Field(..., description="Raw invite token from the email link")
    first_name: str = Field(..., min_length=1, max_length=100, description="First name")
    last_name: str = Field(..., min_length=1, max_length=100, description="Last name")
    password: str = Field(..., min_length=8, description="Password for the new account")


class ChangeMemberRoleRequest(BaseSchema):
    role_id: int = Field(..., description="ID of the new role to assign")


class TransferOwnershipRequest(BaseSchema):
    to_user_id: int = Field(..., description="User ID of the new owner")


class CreateRoleRequest(BaseSchema):
    label: str = Field(..., min_length=1, max_length=100, description="Role display name")
    permission_ids: List[int] = Field(..., description="List of permission IDs")
    role_rank: Optional[int] = Field(None, ge=1, le=2, description="Role level: 1=Standard, 2=Mid-level (Owner only)")


class UpdateRoleRequest(BaseSchema):
    label: Optional[str] = Field(None, min_length=1, max_length=100, description="Updated role name")
    permission_ids: Optional[List[int]] = Field(None, description="Updated list of permission IDs")
    role_rank: Optional[int] = Field(None, ge=1, le=2, description="Role level: 1=Standard, 2=Mid-level (Owner only)")
