# app/modules/core/routes/api/store_settings.py
"""
Store settings and configuration endpoints.

Store Context: Uses token_store_id from JWT token (authenticated store API pattern).
The get_current_store_api dependency guarantees token_store_id is present.
"""

import logging

from fastapi import APIRouter, Depends
from pydantic import BaseModel, Field, field_validator
from sqlalchemy.orm import Session

from app.api.deps import get_current_store_api
from app.core.database import get_db
from app.modules.core.services.platform_settings_service import (
    platform_settings_service,
)
from app.modules.tenancy.schemas.auth import UserContext
from app.modules.tenancy.services.store_service import store_service

store_settings_router = APIRouter(prefix="/settings")
logger = logging.getLogger(__name__)

# Supported languages for dropdown
SUPPORTED_LANGUAGES = [
    {"code": "en", "name": "English"},
    {"code": "fr", "name": "Français"},
    {"code": "de", "name": "Deutsch"},
    {"code": "lb", "name": "Lëtzebuergesch"},
]

# Supported locales for currency/number formatting
SUPPORTED_LOCALES = [
    {"code": "fr-LU", "name": "Luxembourg (French)", "example": "29,99 €"},
    {"code": "de-LU", "name": "Luxembourg (German)", "example": "29,99 €"},
    {"code": "de-DE", "name": "Germany", "example": "29,99 €"},
    {"code": "fr-FR", "name": "France", "example": "29,99 €"},
    {"code": "en-GB", "name": "United Kingdom", "example": "€29.99"},
]


# Valid language codes for validation
VALID_LANGUAGE_CODES = {"en", "fr", "de", "lb"}

# Valid locale codes for validation
VALID_LOCALE_CODES = {"fr-LU", "de-LU", "de-DE", "fr-FR", "en-GB"}


class LocalizationSettingsUpdate(BaseModel):
    """Schema for updating localization settings."""

    default_language: str | None = Field(
        None, description="Default language for store content"
    )
    dashboard_language: str | None = Field(
        None, description="Language for store dashboard UI"
    )
    storefront_language: str | None = Field(
        None, description="Default language for customer storefront"
    )
    storefront_languages: list[str] | None = Field(
        None, description="Enabled languages for storefront selector"
    )
    storefront_locale: str | None = Field(
        None, description="Locale for currency/number formatting"
    )

    @field_validator("default_language", "dashboard_language", "storefront_language")
    @classmethod
    def validate_language(cls, v: str | None) -> str | None:
        if v is not None and v not in VALID_LANGUAGE_CODES:
            raise ValueError(f"Invalid language: {v}. Must be one of: {sorted(VALID_LANGUAGE_CODES)}")
        return v

    @field_validator("storefront_languages")
    @classmethod
    def validate_storefront_languages(cls, v: list[str] | None) -> list[str] | None:
        if v is not None:
            for lang in v:
                if lang not in VALID_LANGUAGE_CODES:
                    raise ValueError(f"Invalid language: {lang}. Must be one of: {sorted(VALID_LANGUAGE_CODES)}")
        return v

    @field_validator("storefront_locale")
    @classmethod
    def validate_locale(cls, v: str | None) -> str | None:
        if v is not None and v not in VALID_LOCALE_CODES:
            raise ValueError(f"Invalid locale: {v}. Must be one of: {sorted(VALID_LOCALE_CODES)}")
        return v


class BusinessInfoUpdate(BaseModel):
    """Schema for updating business info (can override merchant values)."""

    name: str | None = Field(None, description="Store/brand name")
    description: str | None = Field(None, description="Store description")
    contact_email: str | None = Field(None, description="Contact email (null = inherit from merchant)")
    contact_phone: str | None = Field(None, description="Contact phone (null = inherit from merchant)")
    website: str | None = Field(None, description="Website URL (null = inherit from merchant)")
    business_address: str | None = Field(None, description="Business address (null = inherit from merchant)")
    tax_number: str | None = Field(None, description="Tax/VAT number (null = inherit from merchant)")
    reset_to_merchant: list[str] | None = Field(
        None, description="List of fields to reset to merchant values (e.g., ['contact_email', 'website'])"
    )


# Valid Letzshop tax rates
VALID_TAX_RATES = [0, 3, 8, 14, 17]

# Valid delivery methods
VALID_DELIVERY_METHODS = ["nationwide", "package_delivery", "self_collect"]


class LetzshopFeedSettingsUpdate(BaseModel):
    """Schema for updating Letzshop feed settings."""

    letzshop_csv_url_fr: str | None = Field(None, description="French CSV feed URL")
    letzshop_csv_url_en: str | None = Field(None, description="English CSV feed URL")
    letzshop_csv_url_de: str | None = Field(None, description="German CSV feed URL")
    letzshop_default_tax_rate: int | None = Field(None, description="Default VAT rate (0, 3, 8, 14, 17)")
    letzshop_boost_sort: str | None = Field(None, description="Sort priority (0.0-10.0)")
    letzshop_delivery_method: str | None = Field(None, description="Delivery method")
    letzshop_preorder_days: int | None = Field(None, ge=0, description="Pre-order lead time in days")

    @field_validator("letzshop_default_tax_rate")
    @classmethod
    def validate_tax_rate(cls, v: int | None) -> int | None:
        if v is not None and v not in VALID_TAX_RATES:
            raise ValueError(f"Invalid tax rate. Must be one of: {VALID_TAX_RATES}")
        return v

    @field_validator("letzshop_delivery_method")
    @classmethod
    def validate_delivery_method(cls, v: str | None) -> str | None:
        if v is not None:
            methods = v.split(",")
            for method in methods:
                if method.strip() not in VALID_DELIVERY_METHODS:
                    raise ValueError(f"Invalid delivery method. Must be one of: {VALID_DELIVERY_METHODS}")
        return v

    @field_validator("letzshop_boost_sort")
    @classmethod
    def validate_boost_sort(cls, v: str | None) -> str | None:
        if v is not None:
            try:
                boost = float(v)
                if boost < 0.0 or boost > 10.0:
                    raise ValueError("Boost sort must be between 0.0 and 10.0")
            except ValueError as e:
                if "could not convert" in str(e).lower():
                    raise ValueError("Boost sort must be a valid number")
                raise
        return v


@store_settings_router.get("")
def get_store_settings(
    current_user: UserContext = Depends(get_current_store_api),
    db: Session = Depends(get_db),
):
    """Get comprehensive store settings and configuration."""
    store = store_service.get_store_by_id(db, current_user.token_store_id)

    # Get platform defaults for display
    platform_config = platform_settings_service.get_storefront_config(db)

    # Get business info with inheritance flags
    contact_info = store.get_contact_info_with_inheritance()

    # Get invoice settings if exists
    invoice_settings = None
    if store.invoice_settings:
        inv = store.invoice_settings
        invoice_settings = {
            "merchant_name": inv.merchant_name,
            "merchant_address": inv.merchant_address,
            "merchant_city": inv.merchant_city,
            "merchant_postal_code": inv.merchant_postal_code,
            "merchant_country": inv.merchant_country,
            "vat_number": inv.vat_number,
            "is_vat_registered": inv.is_vat_registered,
            "invoice_prefix": inv.invoice_prefix,
            "invoice_next_number": inv.invoice_next_number,
            "payment_terms": inv.payment_terms,
            "bank_name": inv.bank_name,
            "bank_iban": inv.bank_iban,
            "bank_bic": inv.bank_bic,
            "footer_text": inv.footer_text,
            "default_vat_rate": inv.default_vat_rate,
        }

    # Get theme settings if exists
    theme_settings = None
    if store.store_theme:
        theme = store.store_theme
        theme_settings = {
            "theme_name": theme.theme_name,
            "colors": theme.colors,
            "font_family_heading": theme.font_family_heading,
            "font_family_body": theme.font_family_body,
            "logo_url": theme.logo_url,
            "logo_dark_url": theme.logo_dark_url,
            "favicon_url": theme.favicon_url,
            "banner_url": theme.banner_url,
            "layout_style": theme.layout_style,
            "header_style": theme.header_style,
            "product_card_style": theme.product_card_style,
            "social_links": theme.social_links,
            "custom_css": theme.custom_css,
        }

    # Get domains (read-only)
    domains = []
    for domain in store.domains:
        domains.append({
            "id": domain.id,
            "domain": domain.domain,
            "is_primary": domain.is_primary,
            "is_active": domain.is_active,
            "ssl_status": domain.ssl_status,
            "is_verified": domain.is_verified,
        })

    return {
        # General info
        "store_code": store.store_code,
        "subdomain": store.subdomain,
        "name": store.name,
        "description": store.description,
        "is_active": store.is_active,
        "is_verified": store.is_verified,

        # Business info with inheritance (values + flags)
        "business_info": {
            "contact_email": contact_info["contact_email"],
            "contact_email_inherited": contact_info["contact_email_inherited"],
            "contact_email_override": store.contact_email,  # Raw override value
            "contact_phone": contact_info["contact_phone"],
            "contact_phone_inherited": contact_info["contact_phone_inherited"],
            "contact_phone_override": store.contact_phone,
            "website": contact_info["website"],
            "website_inherited": contact_info["website_inherited"],
            "website_override": store.website,
            "business_address": contact_info["business_address"],
            "business_address_inherited": contact_info["business_address_inherited"],
            "business_address_override": store.business_address,
            "tax_number": contact_info["tax_number"],
            "tax_number_inherited": contact_info["tax_number_inherited"],
            "tax_number_override": store.tax_number,
            "merchant_name": store.merchant.name if store.merchant else None,
        },

        # Localization settings
        "localization": {
            "default_language": store.default_language,
            "dashboard_language": store.dashboard_language,
            "storefront_language": store.storefront_language,
            "storefront_languages": store.storefront_languages or ["fr", "de", "en"],
            "storefront_locale": store.storefront_locale,
            "platform_default_locale": platform_config["locale"],
            "platform_currency": platform_config["currency"],
        },

        # Letzshop marketplace settings
        "letzshop": {
            "csv_url_fr": store.letzshop_csv_url_fr,
            "csv_url_en": store.letzshop_csv_url_en,
            "csv_url_de": store.letzshop_csv_url_de,
            "default_tax_rate": store.letzshop_default_tax_rate,
            "boost_sort": store.letzshop_boost_sort,
            "delivery_method": store.letzshop_delivery_method,
            "preorder_days": store.letzshop_preorder_days,
            "store_id": store.letzshop_store_id,
            "store_slug": store.letzshop_store_slug,
            "has_credentials": store.letzshop_credentials is not None,
            "auto_sync_enabled": store.letzshop_credentials.auto_sync_enabled if store.letzshop_credentials else False,
        },

        # Invoice settings
        "invoice_settings": invoice_settings,

        # Theme/branding settings
        "theme_settings": theme_settings,

        # Domains (read-only)
        "domains": domains,
        "default_subdomain": f"{store.subdomain}.letzshop.lu",

        # Options for dropdowns
        "options": {
            "supported_languages": SUPPORTED_LANGUAGES,
            "supported_locales": SUPPORTED_LOCALES,
            "tax_rates": [
                {"value": 0, "label": "0% (Exempt)"},
                {"value": 3, "label": "3% (Super-reduced)"},
                {"value": 8, "label": "8% (Reduced)"},
                {"value": 14, "label": "14% (Intermediate)"},
                {"value": 17, "label": "17% (Standard)"},
            ],
            "delivery_methods": [
                {"value": "nationwide", "label": "Nationwide (all methods)"},
                {"value": "package_delivery", "label": "Package Delivery"},
                {"value": "self_collect", "label": "Self Collect"},
            ],
        },
    }


@store_settings_router.put("/business-info")
def update_business_info(
    business_info: BusinessInfoUpdate,
    current_user: UserContext = Depends(get_current_store_api),
    db: Session = Depends(get_db),
):
    """
    Update store business info.

    Fields can be set to override merchant values, or reset to inherit from merchant.
    Use reset_to_merchant list to reset specific fields to inherit from merchant.
    """
    store = store_service.get_store_by_id(db, current_user.token_store_id)
    update_data = business_info.model_dump(exclude_unset=True)

    # Handle reset_to_merchant - set those fields to None
    reset_fields = update_data.pop("reset_to_merchant", None) or []
    for field in reset_fields:
        if field in ["contact_email", "contact_phone", "website", "business_address", "tax_number"]:
            setattr(store, field, None)
            logger.info(f"Reset {field} to inherit from merchant for store {store.id}")

    # Update other fields
    for key, value in update_data.items():
        if key in ["name", "description", "contact_email", "contact_phone", "website", "business_address", "tax_number"]:
            setattr(store, key, value)

    db.commit()
    db.refresh(store)

    logger.info(f"Business info updated for store {store.id}")

    # Return updated info with inheritance
    contact_info = store.get_contact_info_with_inheritance()
    return {
        "message": "Business info updated",
        "name": store.name,
        "description": store.description,
        "business_info": contact_info,
    }


@store_settings_router.put("/letzshop")
def update_letzshop_settings(
    letzshop_config: LetzshopFeedSettingsUpdate,
    current_user: UserContext = Depends(get_current_store_api),
    db: Session = Depends(get_db),
):
    """Update Letzshop marketplace feed settings.

    Validation is handled by Pydantic model validators.
    """
    store = store_service.get_store_by_id(db, current_user.token_store_id)
    update_data = letzshop_config.model_dump(exclude_unset=True)

    # Apply updates (validation already done by Pydantic)
    for key, value in update_data.items():
        setattr(store, key, value)

    db.commit()
    db.refresh(store)

    logger.info(f"Letzshop settings updated for store {store.id}")

    return {
        "message": "Letzshop settings updated",
        "csv_url_fr": store.letzshop_csv_url_fr,
        "csv_url_en": store.letzshop_csv_url_en,
        "csv_url_de": store.letzshop_csv_url_de,
        "default_tax_rate": store.letzshop_default_tax_rate,
        "boost_sort": store.letzshop_boost_sort,
        "delivery_method": store.letzshop_delivery_method,
        "preorder_days": store.letzshop_preorder_days,
    }


@store_settings_router.put("/localization")
def update_localization_settings(
    localization_config: LocalizationSettingsUpdate,
    current_user: UserContext = Depends(get_current_store_api),
    db: Session = Depends(get_db),
):
    """
    Update store localization settings.

    Allows stores to configure:
    - default_language: Default language for store content
    - dashboard_language: UI language for store dashboard
    - storefront_language: Default language for customer storefront
    - storefront_languages: Enabled languages for storefront selector
    - storefront_locale: Locale for currency/number formatting (or null for platform default)

    Validation is handled by Pydantic model validators.
    """
    store = store_service.get_store_by_id(db, current_user.token_store_id)

    # Update only provided fields (validation already done by Pydantic)
    update_data = localization_config.model_dump(exclude_unset=True)

    # Apply updates
    for key, value in update_data.items():
        setattr(store, key, value)

    db.commit()
    db.refresh(store)

    logger.info(
        f"Localization settings updated for store {store.id}",
        extra={"store_id": store.id, "updated_fields": list(update_data.keys())},
    )

    return {
        "message": "Localization settings updated",
        "default_language": store.default_language,
        "dashboard_language": store.dashboard_language,
        "storefront_language": store.storefront_language,
        "storefront_languages": store.storefront_languages,
        "storefront_locale": store.storefront_locale,
    }
