# app/modules/marketplace/models/onboarding.py
"""
Store onboarding progress tracking.

Tracks completion status of mandatory onboarding steps for new stores.
Onboarding must be completed before accessing the store dashboard.

The onboarding flow guides stores through Letzshop marketplace integration:
1. Merchant Profile setup
2. Letzshop API configuration
3. Product import from CSV feed
4. Historical order sync
"""

import enum
from datetime import datetime

from sqlalchemy import (
    Boolean,
    Column,
    DateTime,
    ForeignKey,
    Index,
    Integer,
    String,
    Text,
)
from sqlalchemy.dialects.sqlite import JSON
from sqlalchemy.orm import relationship

from app.core.database import Base
from models.database.base import TimestampMixin


class OnboardingStep(str, enum.Enum):
    """Onboarding step identifiers."""

    MERCHANT_PROFILE = "merchant_profile"
    LETZSHOP_API = "letzshop_api"
    PRODUCT_IMPORT = "product_import"
    ORDER_SYNC = "order_sync"


class OnboardingStatus(str, enum.Enum):
    """Overall onboarding status."""

    NOT_STARTED = "not_started"
    IN_PROGRESS = "in_progress"
    COMPLETED = "completed"
    SKIPPED = "skipped"  # For admin override capability


# Step order for validation
STEP_ORDER = [
    OnboardingStep.MERCHANT_PROFILE,
    OnboardingStep.LETZSHOP_API,
    OnboardingStep.PRODUCT_IMPORT,
    OnboardingStep.ORDER_SYNC,
]


class StoreOnboarding(Base, TimestampMixin):
    """
    Per-store onboarding progress tracking.

    Created automatically when store is created during signup.
    Blocks dashboard access until status = 'completed' or skipped_by_admin = True.
    """

    __tablename__ = "store_onboarding"

    id = Column(Integer, primary_key=True, index=True)
    store_id = Column(
        Integer,
        ForeignKey("stores.id", ondelete="CASCADE"),
        unique=True,
        nullable=False,
        index=True,
    )

    # Overall status
    status = Column(
        String(20),
        default=OnboardingStatus.NOT_STARTED.value,
        nullable=False,
        index=True,
    )
    current_step = Column(
        String(30),
        default=OnboardingStep.MERCHANT_PROFILE.value,
        nullable=False,
    )

    # Step 1: Merchant Profile
    step_merchant_profile_completed = Column(Boolean, default=False, nullable=False)
    step_merchant_profile_completed_at = Column(DateTime(timezone=True), nullable=True)
    step_merchant_profile_data = Column(JSON, nullable=True)  # Store what was entered

    # Step 2: Letzshop API Configuration
    step_letzshop_api_completed = Column(Boolean, default=False, nullable=False)
    step_letzshop_api_completed_at = Column(DateTime(timezone=True), nullable=True)
    step_letzshop_api_connection_verified = Column(Boolean, default=False, nullable=False)

    # Step 3: Product & Order Import (CSV feed URL + historical import)
    step_product_import_completed = Column(Boolean, default=False, nullable=False)
    step_product_import_completed_at = Column(DateTime(timezone=True), nullable=True)
    step_product_import_csv_url_set = Column(Boolean, default=False, nullable=False)

    # Step 4: Order Sync
    step_order_sync_completed = Column(Boolean, default=False, nullable=False)
    step_order_sync_completed_at = Column(DateTime(timezone=True), nullable=True)
    step_order_sync_job_id = Column(Integer, nullable=True)  # FK to LetzshopHistoricalImportJob

    # Completion tracking
    started_at = Column(DateTime(timezone=True), nullable=True)
    completed_at = Column(DateTime(timezone=True), nullable=True)

    # Admin override (for support cases)
    skipped_by_admin = Column(Boolean, default=False, nullable=False)
    skipped_at = Column(DateTime(timezone=True), nullable=True)
    skipped_reason = Column(Text, nullable=True)
    skipped_by_user_id = Column(Integer, ForeignKey("users.id"), nullable=True)

    # Relationships
    store = relationship("Store", back_populates="onboarding")

    __table_args__ = (
        Index("idx_onboarding_store_status", "store_id", "status"),
        {"sqlite_autoincrement": True},
    )

    def __repr__(self):
        return f"<StoreOnboarding(store_id={self.store_id}, status='{self.status}', step='{self.current_step}')>"

    @property
    def is_completed(self) -> bool:
        """Check if onboarding is fully completed or skipped."""
        return (
            self.status == OnboardingStatus.COMPLETED.value or self.skipped_by_admin
        )

    @property
    def completion_percentage(self) -> int:
        """Calculate completion percentage (0-100)."""
        completed_steps = sum(
            [
                self.step_merchant_profile_completed,
                self.step_letzshop_api_completed,
                self.step_product_import_completed,
                self.step_order_sync_completed,
            ]
        )
        return int((completed_steps / 4) * 100)

    @property
    def completed_steps_count(self) -> int:
        """Get number of completed steps."""
        return sum(
            [
                self.step_merchant_profile_completed,
                self.step_letzshop_api_completed,
                self.step_product_import_completed,
                self.step_order_sync_completed,
            ]
        )

    def is_step_completed(self, step: str) -> bool:
        """Check if a specific step is completed."""
        step_mapping = {
            OnboardingStep.MERCHANT_PROFILE.value: self.step_merchant_profile_completed,
            OnboardingStep.LETZSHOP_API.value: self.step_letzshop_api_completed,
            OnboardingStep.PRODUCT_IMPORT.value: self.step_product_import_completed,
            OnboardingStep.ORDER_SYNC.value: self.step_order_sync_completed,
        }
        return step_mapping.get(step, False)

    def can_proceed_to_step(self, step: str) -> bool:
        """Check if user can proceed to a specific step (no skipping)."""
        target_index = None
        for i, s in enumerate(STEP_ORDER):
            if s.value == step:
                target_index = i
                break

        if target_index is None:
            return False

        # Check all previous steps are completed
        for i in range(target_index):
            if not self.is_step_completed(STEP_ORDER[i].value):
                return False

        return True

    def get_next_step(self) -> str | None:
        """Get the next incomplete step."""
        for step in STEP_ORDER:
            if not self.is_step_completed(step.value):
                return step.value
        return None

    def mark_step_complete(self, step: str, timestamp: datetime | None = None) -> None:
        """Mark a step as complete and update current step."""
        if timestamp is None:
            timestamp = datetime.utcnow()

        if step == OnboardingStep.MERCHANT_PROFILE.value:
            self.step_merchant_profile_completed = True
            self.step_merchant_profile_completed_at = timestamp
        elif step == OnboardingStep.LETZSHOP_API.value:
            self.step_letzshop_api_completed = True
            self.step_letzshop_api_completed_at = timestamp
        elif step == OnboardingStep.PRODUCT_IMPORT.value:
            self.step_product_import_completed = True
            self.step_product_import_completed_at = timestamp
        elif step == OnboardingStep.ORDER_SYNC.value:
            self.step_order_sync_completed = True
            self.step_order_sync_completed_at = timestamp

        # Update current step to next incomplete step
        next_step = self.get_next_step()
        if next_step:
            self.current_step = next_step
        else:
            # All steps complete
            self.status = OnboardingStatus.COMPLETED.value
            self.completed_at = timestamp
