"""CRM domain enums and dialect-safe GUID type."""
from __future__ import annotations

import enum
import uuid

from sqlalchemy.dialects.postgresql import UUID as PG_UUID
from sqlalchemy.types import CHAR, TypeDecorator


class GUID(TypeDecorator):
    impl = CHAR
    cache_ok = True

    def load_dialect_impl(self, dialect):
        if dialect.name == "postgresql":
            return dialect.type_descriptor(PG_UUID(as_uuid=True))
        return dialect.type_descriptor(CHAR(36))

    def process_bind_param(self, value, dialect):
        if value is None:
            return value
        if dialect.name == "postgresql":
            return value if isinstance(value, uuid.UUID) else uuid.UUID(str(value))
        return str(value)

    def process_result_value(self, value, dialect):
        if value is None:
            return value
        if isinstance(value, uuid.UUID):
            return value
        return uuid.UUID(str(value))


# --- Legacy / pipeline enums (Phase 6.0) ---


class LeadStatus(str, enum.Enum):
    """Built-in lead lifecycle codes (also mirrored by lead_statuses table)."""

    NEW = "new"
    CONTACTED = "contacted"
    QUALIFIED = "qualified"
    DISQUALIFIED = "disqualified"
    CONVERTED = "converted"


class ContactStatus(str, enum.Enum):
    ACTIVE = "active"
    INACTIVE = "inactive"
    ARCHIVED = "archived"


class OrganizationStatus(str, enum.Enum):
    ACTIVE = "active"
    INACTIVE = "inactive"
    ARCHIVED = "archived"


class OpportunityStatus(str, enum.Enum):
    OPEN = "open"
    WON = "won"
    LOST = "lost"
    ABANDONED = "abandoned"


class ActivityType(str, enum.Enum):
    MEETING = "meeting"
    CALL = "call"
    TASK = "task"
    EMAIL = "email"
    FOLLOW_UP = "follow_up"
    VISIT = "visit"
    DEMO = "demo"
    PRESENTATION = "presentation"
    NEGOTIATION = "negotiation"
    NOTE = "note"
    CUSTOM = "custom"
    OTHER = "other"


class ActivityStatus(str, enum.Enum):
    PLANNED = "planned"
    IN_PROGRESS = "in_progress"
    COMPLETED = "completed"
    CANCELLED = "cancelled"


class ActivityPriority(str, enum.Enum):
    LOW = "low"
    MEDIUM = "medium"
    HIGH = "high"
    URGENT = "urgent"


class ActivityRelatedType(str, enum.Enum):
    LEAD = "lead"
    CONTACT = "contact"
    ORGANIZATION = "organization"
    OPPORTUNITY = "opportunity"
    QUOTE = "quote"


class QuoteStatus(str, enum.Enum):
    DRAFT = "draft"
    SENT = "sent"
    ACCEPTED = "accepted"
    REJECTED = "rejected"
    EXPIRED = "expired"
    CANCELLED = "cancelled"


# --- Phase 6.1 enums ---


class LeadPriority(str, enum.Enum):
    LOW = "low"
    MEDIUM = "medium"
    HIGH = "high"
    URGENT = "urgent"


class ContactKind(str, enum.Enum):
    PERSONAL = "personal"
    BUSINESS = "business"


class OrganizationKind(str, enum.Enum):
    COMPANY = "company"
    BRANCH = "branch"
    DEPARTMENT = "department"


class AddressType(str, enum.Enum):
    OFFICE = "office"
    BILLING = "billing"
    SHIPPING = "shipping"
    HOME = "home"
    BRANCH = "branch"
    HEAD_OFFICE = "head_office"


class ContactMethod(str, enum.Enum):
    EMAIL = "email"
    MOBILE = "mobile"
    PHONE = "phone"
    SOCIAL = "social"


class CustomFieldType(str, enum.Enum):
    TEXT = "text"
    NUMBER = "number"
    BOOLEAN = "boolean"
    DATE = "date"
    SELECT = "select"
    MULTI_SELECT = "multi_select"


class CrmEntityType(str, enum.Enum):
    LEAD = "lead"
    CONTACT = "contact"
    ORGANIZATION = "organization"


class AuditAction(str, enum.Enum):
    CREATE = "create"
    UPDATE = "update"
    DELETE = "delete"
    RESTORE = "restore"
    ASSIGNMENT = "assignment"
    STATUS_CHANGE = "status_change"
    FIELD_CHANGE = "field_change"


class AttachmentKind(str, enum.Enum):
    DOCUMENT = "document"
    IMAGE = "image"
    PDF = "pdf"
    CONTRACT = "contract"
    OTHER = "other"


class TagScope(str, enum.Enum):
    LEAD = "lead"
    CONTACT = "contact"
    ORGANIZATION = "organization"
    ANY = "any"


# --- Phase 6.2 sales engine enums ---


class OpportunityPriority(str, enum.Enum):
    LOW = "low"
    MEDIUM = "medium"
    HIGH = "high"
    CRITICAL = "critical"


class PipelineLifecycleStatus(str, enum.Enum):
    ACTIVE = "active"
    INACTIVE = "inactive"
    ARCHIVED = "archived"


class ContactRoleType(str, enum.Enum):
    DECISION_MAKER = "decision_maker"
    INFLUENCER = "influencer"
    TECHNICAL = "technical"
    FINANCIAL = "financial"
    LEGAL = "legal"
    CUSTOM = "custom"


class ForecastPeriod(str, enum.Enum):
    MONTHLY = "monthly"
    QUARTERLY = "quarterly"
    ANNUAL = "annual"


class ForecastKind(str, enum.Enum):
    PIPELINE = "pipeline"
    WEIGHTED = "weighted"
    COMMITTED = "committed"


class GoalScope(str, enum.Enum):
    INDIVIDUAL = "individual"
    TEAM = "team"
    DEPARTMENT = "department"


class GoalMetric(str, enum.Enum):
    REVENUE = "revenue"
    OPPORTUNITY_COUNT = "opportunity_count"


class TargetPeriod(str, enum.Enum):
    MONTHLY = "monthly"
    QUARTERLY = "quarterly"
    ANNUAL = "annual"


class PlaybookStepKind(str, enum.Enum):
    REQUIRED_ACTIVITY = "required_activity"
    RECOMMENDED_ACTIVITY = "recommended_activity"
    CHECKLIST = "checklist"
    TEMPLATE = "template"


class PlaybookAssignmentStatus(str, enum.Enum):
    ASSIGNED = "assigned"
    IN_PROGRESS = "in_progress"
    COMPLETED = "completed"
    CANCELLED = "cancelled"


class WinLossOutcome(str, enum.Enum):
    WON = "won"
    LOST = "lost"


# --- Phase 6.3 collaboration enums ---


class CollaborationEntityType(str, enum.Enum):
    LEAD = "lead"
    CONTACT = "contact"
    ORGANIZATION = "organization"
    OPPORTUNITY = "opportunity"
    ACTIVITY = "activity"
    TASK = "task"
    MEETING = "meeting"
    CALL = "call"
    EMAIL = "email"
    QUOTE = "quote"


class TimelineEventType(str, enum.Enum):
    LEAD_CREATED = "lead_created"
    CONTACT_CREATED = "contact_created"
    ORGANIZATION_UPDATED = "organization_updated"
    OPPORTUNITY_CREATED = "opportunity_created"
    STAGE_CHANGED = "stage_changed"
    ACTIVITY_CREATED = "activity_created"
    MEETING_HELD = "meeting_held"
    CALL_LOGGED = "call_logged"
    EMAIL_SENT = "email_sent"
    TASK_COMPLETED = "task_completed"
    NOTE_ADDED = "note_added"
    ATTACHMENT_ADDED = "attachment_added"
    COMMENT_ADDED = "comment_added"
    MENTION_ADDED = "mention_added"


class CallDirection(str, enum.Enum):
    INBOUND = "inbound"
    OUTBOUND = "outbound"


class EmailDeliveryStatus(str, enum.Enum):
    DRAFT = "draft"
    QUEUED = "queued"
    SENT = "sent"
    OPENED = "opened"
    CLICKED = "clicked"
    FAILED = "failed"
    BOUNCED = "bounced"


class TeamRoleCode(str, enum.Enum):
    SALESPERSON = "salesperson"
    MANAGER = "manager"
    SUPERVISOR = "supervisor"
    VIEWER = "viewer"
    CUSTOM = "custom"


class RecurrenceRule(str, enum.Enum):
    NONE = "none"
    DAILY = "daily"
    WEEKLY = "weekly"
    MONTHLY = "monthly"
