#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Demo POS Configurations Seeding Script for POS Service
Creates realistic POS configurations and transactions for demo template tenants

This script runs as a Kubernetes init job inside the pos-service container.
"""

import asyncio
import uuid
import sys
import os
from datetime import datetime, timezone, timedelta
from pathlib import Path

# Add app to path
sys.path.insert(0, str(Path(__file__).parent.parent.parent))

from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy import select
import structlog

from app.models.pos_config import POSConfiguration
from app.models.pos_transaction import POSTransaction, POSTransactionItem

# Configure logging
logger = structlog.get_logger()

# Base demo tenant IDs
DEMO_TENANT_SAN_PABLO = uuid.UUID("a1b2c3d4-e5f6-47a8-b9c0-d1e2f3a4b5c6")  # Individual bakery
DEMO_TENANT_LA_ESPIGA = uuid.UUID("b2c3d4e5-f6a7-48b9-c0d1-e2f3a4b5c6d7")  # Central bakery

# Base reference date for date calculations
BASE_REFERENCE_DATE = datetime(2025, 1, 15, 12, 0, 0, tzinfo=timezone.utc)


async def generate_pos_config_for_tenant(
    db: AsyncSession,
    tenant_id: uuid.UUID,
    tenant_name: str,
    pos_system: str,
    provider_name: str
):
    """Generate a demo POS configuration for a tenant"""
    logger.info(f"Generating POS config for: {tenant_name}", tenant_id=str(tenant_id), pos_system=pos_system)

    # Check if config already exists
    result = await db.execute(
        select(POSConfiguration).where(
            POSConfiguration.tenant_id == tenant_id,
            POSConfiguration.pos_system == pos_system
        ).limit(1)
    )
    existing = result.scalar_one_or_none()

    if existing:
        logger.info(f"POS config already exists for {tenant_name}, skipping")
        return {"tenant_id": str(tenant_id), "configs_created": 0, "skipped": True}

    # Create demo POS configuration
    config = POSConfiguration(
        id=uuid.uuid4(),
        tenant_id=tenant_id,
        pos_system=pos_system,
        provider_name=provider_name,
        is_active=True,
        is_connected=True,
        encrypted_credentials="demo_credentials_encrypted",  # In real scenario, this would be encrypted
        environment="sandbox",
        location_id=f"LOC-{tenant_name.replace(' ', '-').upper()}-001",
        merchant_id=f"MERCH-{tenant_name.replace(' ', '-').upper()}",
        sync_enabled=True,
        sync_interval_minutes="5",
        auto_sync_products=True,
        auto_sync_transactions=True,
        last_sync_at=BASE_REFERENCE_DATE - timedelta(hours=1),
        last_successful_sync_at=BASE_REFERENCE_DATE - timedelta(hours=1),
        last_sync_status="success",
        last_sync_message="Sincronización completada exitosamente",
        provider_settings={
            "api_key": "demo_api_key_***",
            "location_id": f"LOC-{tenant_name.replace(' ', '-').upper()}-001",
            "environment": "sandbox"
        },
        last_health_check_at=BASE_REFERENCE_DATE - timedelta(minutes=30),
        health_status="healthy",
        health_message="Conexión saludable - todas las operaciones funcionando correctamente",
        created_at=BASE_REFERENCE_DATE - timedelta(days=30),
        updated_at=BASE_REFERENCE_DATE - timedelta(hours=1),
        notes=f"Configuración demo para {tenant_name}"
    )

    db.add(config)
    await db.flush()

    logger.info(f"Created POS config for {tenant_name}", config_id=str(config.id))

    # Generate demo transactions
    transactions_created = await generate_demo_transactions(db, tenant_id, config.id, pos_system)

    return {
        "tenant_id": str(tenant_id),
        "configs_created": 1,
        "transactions_created": transactions_created,
        "skipped": False
    }


async def generate_demo_transactions(
    db: AsyncSession,
    tenant_id: uuid.UUID,
    pos_config_id: uuid.UUID,
    pos_system: str
):
    """Generate demo POS transactions"""
    transactions_to_create = 10  # Create 10 demo transactions
    transactions_created = 0

    for i in range(transactions_to_create):
        # Calculate transaction date (spread over last 7 days)
        days_ago = i % 7
        transaction_date = BASE_REFERENCE_DATE - timedelta(days=days_ago, hours=i % 12)

        # Generate realistic transaction amounts
        base_amounts = [12.50, 25.00, 45.75, 18.20, 32.00, 60.50, 15.80, 28.90, 55.00, 40.25]
        subtotal = base_amounts[i % len(base_amounts)]
        tax_amount = round(subtotal * 0.10, 2)  # 10% tax
        total_amount = subtotal + tax_amount

        # Create transaction
        transaction = POSTransaction(
            id=uuid.uuid4(),
            tenant_id=tenant_id,
            pos_config_id=pos_config_id,
            pos_system=pos_system,
            external_transaction_id=f"{pos_system.upper()}-TXN-{i+1:05d}",
            external_order_id=f"{pos_system.upper()}-ORD-{i+1:05d}",
            transaction_type="sale",
            status="completed",
            subtotal=subtotal,
            tax_amount=tax_amount,
            tip_amount=0.00,
            discount_amount=0.00,
            total_amount=total_amount,
            currency="EUR",
            payment_method="card" if i % 2 == 0 else "cash",
            payment_status="paid",
            transaction_date=transaction_date,
            pos_created_at=transaction_date,
            pos_updated_at=transaction_date,
            location_id=f"LOC-001",
            location_name="Tienda Principal",
            order_type="takeout" if i % 3 == 0 else "dine_in",
            receipt_number=f"RCP-{i+1:06d}",
            is_synced_to_sales=True,
            sync_completed_at=transaction_date + timedelta(minutes=5),
            sync_retry_count=0,
            is_processed=True,
            is_duplicate=False,
            created_at=transaction_date,
            updated_at=transaction_date
        )

        db.add(transaction)
        await db.flush()

        # Add transaction items
        num_items = (i % 3) + 1  # 1-3 items per transaction
        for item_idx in range(num_items):
            product_names = [
                "Pan de masa madre", "Croissant de mantequilla", "Pastel de chocolate",
                "Baguette artesanal", "Tarta de manzana", "Bollería variada",
                "Pan integral", "Galletas artesanales", "Café con leche"
            ]

            product_name = product_names[(i + item_idx) % len(product_names)]
            item_price = round(subtotal / num_items, 2)

            item = POSTransactionItem(
                id=uuid.uuid4(),
                transaction_id=transaction.id,
                tenant_id=tenant_id,
                external_item_id=f"ITEM-{i+1:05d}-{item_idx+1}",
                sku=f"SKU-{(i + item_idx) % len(product_names):03d}",
                product_name=product_name,
                product_category="bakery",
                quantity=1,
                unit_price=item_price,
                total_price=item_price,
                discount_amount=0.00,
                tax_amount=round(item_price * 0.10, 2),
                is_mapped_to_inventory=False,
                is_synced_to_sales=True,
                created_at=transaction_date,
                updated_at=transaction_date
            )

            db.add(item)

        transactions_created += 1

    logger.info(f"Created {transactions_created} demo transactions for tenant {tenant_id}")

    return transactions_created


async def seed_all(db: AsyncSession):
    """Seed all demo tenants with POS configurations"""
    logger.info("Starting demo POS configurations seed process")

    results = []

    # Seed San Pablo with Square POS
    result_san_pablo = await generate_pos_config_for_tenant(
        db,
        DEMO_TENANT_SAN_PABLO,
        "San Pablo",
        "square",
        "Square POS - San Pablo"
    )
    results.append(result_san_pablo)

    # Seed La Espiga with Toast POS
    result_la_espiga = await generate_pos_config_for_tenant(
        db,
        DEMO_TENANT_LA_ESPIGA,
        "La Espiga",
        "toast",
        "Toast POS - La Espiga"
    )
    results.append(result_la_espiga)

    await db.commit()

    total_configs = sum(r["configs_created"] for r in results)
    total_transactions = sum(r.get("transactions_created", 0) for r in results)

    return {
        "results": results,
        "total_configs_created": total_configs,
        "total_transactions_created": total_transactions,
        "status": "completed"
    }


async def main():
    """Main execution function"""
    # Get database URL from environment
    database_url = os.getenv("POS_DATABASE_URL")
    if not database_url:
        logger.error("POS_DATABASE_URL environment variable must be set")
        return 1

    # Ensure asyncpg driver
    if database_url.startswith("postgresql://"):
        database_url = database_url.replace("postgresql://", "postgresql+asyncpg://", 1)

    # Create async engine
    engine = create_async_engine(database_url, echo=False)
    async_session = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)

    try:
        async with async_session() as session:
            result = await seed_all(session)

            logger.info(
                "POS configurations seed completed successfully!",
                total_configs=result["total_configs_created"],
                total_transactions=result["total_transactions_created"],
                status=result["status"]
            )

            # Print summary
            print("\n" + "="*60)
            print("DEMO POS CONFIGURATIONS SEED SUMMARY")
            print("="*60)
            for tenant_result in result["results"]:
                tenant_id = tenant_result["tenant_id"]
                configs = tenant_result["configs_created"]
                transactions = tenant_result.get("transactions_created", 0)
                skipped = tenant_result.get("skipped", False)
                status = "SKIPPED (already exists)" if skipped else f"CREATED {configs} config(s), {transactions} transaction(s)"
                print(f"Tenant {tenant_id}: {status}")
            print(f"\nTotal Configs: {result['total_configs_created']}")
            print(f"Total Transactions: {result['total_transactions_created']}")
            print("="*60 + "\n")

            return 0

    except Exception as e:
        logger.error(f"POS configurations seed failed: {str(e)}", exc_info=True)
        return 1
    finally:
        await engine.dispose()


if __name__ == "__main__":
    exit_code = asyncio.run(main())
    sys.exit(exit_code)
