from enum import Enum


class UserRole(str, Enum):
    SITE_ADMIN = "site_admin"
    ADMINISTRATOR = "administrator"
    MANAGER = "manager"
    STAFF = "staff"
    VIEW_ONLY = "view_only"


class AccountStatus(str, Enum):
    LEAD = "lead"
    NEW = "new"
    PENDING = "pending"  # kept for backwards compatibility; backfilled to 'new' by migration 0026
    ONBOARDING = "onboarding"
    ACTIVE = "active"
    SUSPENDED = "suspended"
    CANCELLED = "canceled"


class UserStatus(str, Enum):
    ACTIVE = "active"
    INACTIVE = "inactive"
    INVITED = "invited"


class PlotStatus(str, Enum):
    VACANT = "vacant"
    RESERVED = "reserved"
    OCCUPIED = "occupied"
    HOLD = "hold"


class OpportunityStage(str, Enum):
    INQUIRY = "inquiry"
    SITE_VISIT = "site_visit"
    PROPOSAL_SENT = "proposal_sent"
    PROPOSAL_ACCEPTED = "proposal_accepted"
    CONTRACT_SENT = "contract_sent"
    CONTRACT_SIGNED = "contract_signed"
    DEPOSIT_RECEIVED = "deposit_received"  # kept for backward compat
    PARTIAL_PAYMENT_RECEIVED = "partial_payment_received"
    FULLY_PAID = "fully_paid"
    LOST = "lost"


class CareType(str, Enum):
    PRE_NEED = "pre_need"
    AT_NEED = "at_need"


class ServiceType(str, Enum):
    """Scheduling service types (INDL-36). Free-text at the DB layer (no CHECK);
    this enum bounds the calendar/PDF filter surface only."""

    INTERMENT = "interment"
    MEMORIAL_SERVICE = "memorial_service"
    FOUNDATION_POUR = "foundation_pour"
    CLOSURE = "closure"


class ProposalStatus(str, Enum):
    DRAFT = "draft"
    SENT = "sent"
    ACCEPTED = "accepted"
    DECLINED = "declined"
    EXPIRED = "expired"


class ContractStatus(str, Enum):
    DRAFT = "draft"
    SENT = "sent"
    SIGNED = "signed"
    CANCELLED = "cancelled"


class InvoiceStatus(str, Enum):
    DRAFT = "draft"
    OUTSTANDING = "outstanding"
    PARTIAL = "partial"
    PAID = "paid"
    OVERDUE = "overdue"
    VOID = "void"


class TributeStatus(str, Enum):
    PENDING = "pending"
    APPROVED = "approved"
    REJECTED = "rejected"


class NewsStatus(str, Enum):
    DRAFT = "draft"
    PUBLISHED = "published"


class EmailTriggerKey(str, Enum):
    """Canonical catalog of every automated email trigger event (INDL-54).

    Each value is the `email_templates.template_key` a tenant's editable
    template is looked up by when the corresponding business event fires.
    The catalog is fixed and platform-wide — tenants cannot invent new keys.
    Keep the value strings in sync with the seeded `template_key`s in
    src/apps/settings/services/email_template_service.py:SYSTEM_TEMPLATES
    and the migrations that seed them (0054, 0065).
    """
    # ── Onboarding / users ────────────────────────────────────────────────
    NEW_USER_WELCOME = "new_user_welcome"
    STAFF_INVITATION = "staff_invitation"
    STAFF_INVITATION_RESEND = "staff_invitation_resend"
    # ── Sales / enquiries ─────────────────────────────────────────────────
    CONTACT_ENQUIRY_REPLY = "contact_enquiry_reply"
    LEAD_QUALIFIED = "lead_qualified"
    PROPOSAL_SENT = "proposal_sent"
    PROPOSAL_RESENT = "proposal_resent"
    CONTRACT_SIGNED = "contract_signed"
    CONTRACT_PDF_CONFIRMATION = "contract_pdf_confirmation"
    # ── Billing ───────────────────────────────────────────────────────────
    INVOICE_PAYMENT_RECEIVED = "invoice_payment_received"
    INVOICE_OVERDUE_REMINDER = "invoice_overdue_reminder"
    # ── Scheduling ────────────────────────────────────────────────────────
    SERVICE_SCHEDULED_FAMILY = "service_scheduled_family"
    SERVICE_REMINDER_24H = "service_reminder_24h"
    FIELD_CREW_BRIEFING = "field_crew_briefing"
    # ── Memorials / records (templates seeded, domain trigger pending) ─────
    TRIBUTE_MODERATED = "tribute_moderated"
    DEED_TRANSFERRED = "deed_transferred"
    # ── News ──────────────────────────────────────────────────────────────
    NEWS_NOTIFICATION = "news_notification"


class SubscriptionPlan(str, Enum):
    STARTER = "starter"
    PROFESSIONAL = "professional"
    ENTERPRISE = "enterprise"


class CemeteryType(str, Enum):
    """Single source of truth for cemetery type options.

    Mirrors indelis-admin/src/constants/cemetery.ts and
    indelis-frontend/src/constants/cemetery.ts — keep all three in sync.
    """
    MUNICIPAL = "Municipal cemetery"
    PRIVATE = "Private operator"
    FUNERAL_HOME = "Funeral home group"
    RELIGIOUS = "Religious / heritage trust"


CEMETERY_TYPES = {t.value for t in CemeteryType}

# Single source of truth for accent colour options.
# Mirrors indelis-admin/src/constants/cemetery.ts (ACCENT_COLORS) — keep in sync.
ACCENT_COLOR_OPTIONS = [
    {"value": "#1E4A6E", "label": "Navy (default)"},
    {"value": "#7BB069", "label": "Green"},
    {"value": "#4FA8D9", "label": "Water blue"},
    {"value": "#6B4E8E", "label": "Heritage purple"},
]
ACCENT_COLORS = {o["value"] for o in ACCENT_COLOR_OPTIONS}
DEFAULT_ACCENT_COLOR = ACCENT_COLOR_OPTIONS[0]["value"]


ROLE_HIERARCHY = {
    UserRole.SITE_ADMIN: 99,
    UserRole.ADMINISTRATOR: 4,
    UserRole.MANAGER: 3,
    UserRole.STAFF: 2,
    UserRole.VIEW_ONLY: 1,
}

PLAN_PRICES_CAD = {
    SubscriptionPlan.STARTER: 149.00,
    SubscriptionPlan.PROFESSIONAL: 349.00,
    SubscriptionPlan.ENTERPRISE: 749.00,
}

# Trial period for new accounts. Change this one number to adjust the trial length globally.
TRIAL_DAYS = 14


class EnquiryTriggerSource(str, Enum):
    MANUAL = "MANUAL"
    EMAIL_REPLY = "EMAIL_REPLY"
    QUALIFY = "QUALIFY"
    SIGNUP_COMPLETE = "SIGNUP_COMPLETE"
    SYSTEM_AUTO_CLOSE = "SYSTEM_AUTO_CLOSE"
    MANUAL_CLOSE = "MANUAL_CLOSE"


ENQUIRY_MANUAL_TRANSITIONS: dict[str, set[str]] = {
    "new": {"contacted", "closed"},
    "contacted": {"qualified", "closed"},
    "qualified": set(),
    "closed": set(),
}

STAGE_TRANSITIONS: dict[str, list[str]] = {
    "inquiry": ["site_visit", "lost"],
    "site_visit": ["proposal_sent", "lost"],
    "proposal_sent": ["proposal_accepted", "lost"],
    "proposal_accepted": ["contract_sent", "lost"],
    "contract_sent": ["contract_signed", "lost"],
    # Once a contract is signed the deal is won — it can no longer be marked lost.
    "contract_signed": ["partial_payment_received"],
    "partial_payment_received": ["fully_paid"],
    "fully_paid": [],
    "lost": [],
    "deposit_received": ["partial_payment_received"],  # backward compat
}
TERMINAL_STAGES = {"fully_paid", "lost"}

# Linear ordering of the pipeline, used to enforce forward-only stage moves.
# "lost" is a side-branch, not part of the forward sequence, so it is excluded.
STAGE_ORDER: dict[str, int] = {
    "inquiry": 0,
    "site_visit": 1,
    "proposal_sent": 2,
    "proposal_accepted": 3,
    "contract_sent": 4,
    "contract_signed": 5,
    "deposit_received": 6,  # backward compat, treated like partial_payment_received
    "partial_payment_received": 6,
    "fully_paid": 7,
}

# Stages from which an opportunity may still be marked lost (before contract signature).
LOST_ELIGIBLE_STAGES = {
    "inquiry", "site_visit", "proposal_sent", "proposal_accepted", "contract_sent",
}
