# @File: backend/schemas/whmcs.py
# @Desc: Pydantic models for the WHMCS integration endpoints.
from typing import Any, List, Optional

from pydantic import BaseModel, EmailStr, Field


class WhmcsRegisterRequest(BaseModel):
    firstname: str = Field(..., min_length=1, max_length=60)
    lastname: str = Field(..., min_length=1, max_length=60)
    email: EmailStr
    password: str = Field(..., min_length=6, max_length=128)
    companyname: Optional[str] = Field(default=None, max_length=120)
    address1: str = Field(..., min_length=1, max_length=120)
    address2: Optional[str] = Field(default=None, max_length=120)
    city: str = Field(..., min_length=1, max_length=60)
    state: str = Field(..., min_length=1, max_length=60)
    postcode: str = Field(..., min_length=1, max_length=20)
    country: str = Field(..., min_length=2, max_length=2, description="ISO-2 country code, e.g. 'AE'.")
    phonenumber: str = Field(..., min_length=4, max_length=30)


class WhmcsRegisterResponse(BaseModel):
    client_id: int
    email: EmailStr
    message: str = "Client successfully registered in WHMCS."


class WhmcsProfile(BaseModel):
    client_id: int
    firstname: str
    lastname: str
    fullname: str
    email: str
    company: Optional[str] = None
    address1: Optional[str] = None
    address2: Optional[str] = None
    city: Optional[str] = None
    state: Optional[str] = None
    postcode: Optional[str] = None
    country: Optional[str] = None
    phonenumber: Optional[str] = None
    status: Optional[str] = None
    credit: Optional[str] = None
    currency_code: Optional[str] = None
    num_invoices: Optional[int] = None
    num_due_invoices: Optional[int] = None
    num_products: Optional[int] = None
    num_domains: Optional[int] = None
    num_tickets: Optional[int] = None


class WhmcsService(BaseModel):
    id: int
    product_name: Optional[str] = None
    domain: Optional[str] = None
    status: Optional[str] = None
    regdate: Optional[str] = None
    nextduedate: Optional[str] = None
    billingcycle: Optional[str] = None
    recurringamount: Optional[str] = None
    paymentmethod: Optional[str] = None


class WhmcsInvoice(BaseModel):
    id: int
    invoicenum: Optional[str] = None
    status: Optional[str] = None
    date: Optional[str] = None
    duedate: Optional[str] = None
    datepaid: Optional[str] = None
    total: Optional[str] = None
    currency_code: Optional[str] = None


class WhmcsDomain(BaseModel):
    id: int
    domainname: Optional[str] = None
    status: Optional[str] = None
    registrar: Optional[str] = None
    registrationdate: Optional[str] = None
    expirydate: Optional[str] = None
    recurringamount: Optional[str] = None


class WhmcsEmail(BaseModel):
    """A single email WHMCS has sent to the client (confirmations, invoices, etc.)."""

    id: int
    subject: Optional[str] = None
    date: Optional[str] = None


class WhmcsTicket(BaseModel):
    id: int
    tid: Optional[str] = None
    subject: Optional[str] = None
    status: Optional[str] = None
    priority: Optional[str] = None
    department: Optional[str] = None
    lastreply: Optional[str] = None


class WhmcsTicketReply(BaseModel):
    """A single message on a ticket (initial description OR a follow-up reply).

    `is_staff` lets the UI render staff / client bubbles on the correct side.
    """

    id: Optional[int] = None
    name: Optional[str] = None
    email: Optional[str] = None
    date: Optional[str] = None
    message: Optional[str] = None
    is_staff: bool = False
    attachments: List[str] = Field(default_factory=list)


class WhmcsTicketDetail(BaseModel):
    id: int
    tid: Optional[str] = None
    subject: Optional[str] = None
    status: Optional[str] = None
    priority: Optional[str] = None
    department: Optional[str] = None
    department_id: Optional[int] = None
    date: Optional[str] = None
    lastreply: Optional[str] = None
    messages: List[WhmcsTicketReply] = Field(default_factory=list)


class WhmcsDepartment(BaseModel):
    id: int
    name: str


class WhmcsDepartmentsResponse(BaseModel):
    items: List[WhmcsDepartment]


class WhmcsCreateTicketRequest(BaseModel):
    subject: str = Field(..., min_length=1, max_length=200)
    message: str = Field(..., min_length=1, max_length=20000)
    department_id: int = Field(..., ge=1)
    priority: str = Field(default="Medium")  # Low | Medium | High


class WhmcsCreateTicketResponse(BaseModel):
    id: int
    tid: Optional[str] = None
    message: str = "Ticket created."


class WhmcsReplyTicketRequest(BaseModel):
    message: str = Field(..., min_length=1, max_length=20000)


class WhmcsReplyTicketResponse(BaseModel):
    success: bool = True
    message: str = "Reply sent."


class WhmcsListResponse(BaseModel):
    items: List[Any]
    total: int


class WhmcsUpdateProfileRequest(BaseModel):
    firstname: Optional[str] = Field(default=None, max_length=60)
    lastname: Optional[str] = Field(default=None, max_length=60)
    companyname: Optional[str] = Field(default=None, max_length=120)
    address1: Optional[str] = Field(default=None, max_length=120)
    address2: Optional[str] = Field(default=None, max_length=120)
    city: Optional[str] = Field(default=None, max_length=60)
    state: Optional[str] = Field(default=None, max_length=60)
    postcode: Optional[str] = Field(default=None, max_length=20)
    country: Optional[str] = Field(default=None, max_length=2)
    phonenumber: Optional[str] = Field(default=None, max_length=30)


class WhmcsUpdateProfileResponse(BaseModel):
    success: bool
    message: str = "Profile updated."


class WhmcsForgotPasswordRequest(BaseModel):
    email: EmailStr


class WhmcsForgotPasswordResponse(BaseModel):
    success: bool = True
    message: str = (
        "If an account exists for that email, a password reset link has been sent."
    )


class WhmcsResetPasswordRequest(BaseModel):
    token: str = Field(..., min_length=10, max_length=2048)
    new_password: str = Field(..., min_length=8, max_length=128)


class WhmcsResetPasswordResponse(BaseModel):
    success: bool = True
    message: str = "Your password has been updated. Please sign in with your new password."
    whmcs_synced: bool = False


class WhmcsLoginRequest(BaseModel):
    email: EmailStr
    password: str = Field(..., min_length=1, max_length=256)


class WhmcsLoginResponse(BaseModel):
    token: str
    user_id: str
    email: EmailStr
    name: Optional[str] = None
    client_id: int