"""
Comprehensive Test Data Seed Script
===================================
Run with:
  python seed_test_data.py

Seeds:
- QR Config (bank + UPI details)
- 10 test users with wallets
- 15 distributor purchases (wallet + QR + bank, various products)
- 3 PAYMENT_REVIEW pending orders for admin to approve/reject
- 5 support tickets
- TWM coins grants
- Wallet top-ups for wallet-payment purchases
"""

import os
import sys
import django
from decimal import Decimal
from uuid import uuid4

# ── Django setup ──────────────────────────────────────────────────────────────
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings.dev")
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
django.setup()

# ── Imports (after setup) ─────────────────────────────────────────────────────
from django.db import transaction
from django.utils import timezone

from apps.accounts.models import User
from apps.business.products.models import Product
from apps.business.orders.services.order_service import execute_purchase, create_pending_payment_order
from apps.business.wallet.services.wallet_service import WalletService
from apps.platform.settings.models import QRConfig
from apps.support.models import SupportTicket, SupportTicketMessage
from apps.business.distributor.models import DistributorID
from apps.business.distributor.services.distributor_service import create_distributor_id

# ── Constants ─────────────────────────────────────────────────────────────────

# Main product for MLM purchases (Glyminoh Rice Voucher ₹11,210, Platinum bundle)
MAIN_PRODUCT_ID = "ba1393be-2a85-4ecc-bdb5-3f8fb5d8bef6"

# Physical product (no bundle) for standalone purchase
RICE_PRODUCT_ID = "c99ddb4f-c1c2-42d3-bc36-35973fc70ba0"

TEST_USERS = [
    {"mobile": "9100000001", "first_name": "Alice", "last_name": "Sharma", "email": "alice@test.twm"},
    {"mobile": "9100000002", "first_name": "Bob", "last_name": "Reddy", "email": "bob@test.twm"},
    {"mobile": "9100000003", "first_name": "Carol", "last_name": "Nair", "email": "carol@test.twm"},
    {"mobile": "9100000004", "first_name": "David", "last_name": "Rao", "email": "david@test.twm"},
    {"mobile": "9100000005", "first_name": "Eve", "last_name": "Pillai", "email": "eve@test.twm"},
    {"mobile": "9100000006", "first_name": "Frank", "last_name": "Kumar", "email": "frank@test.twm"},
    {"mobile": "9100000007", "first_name": "Grace", "last_name": "Iyer", "email": "grace@test.twm"},
    {"mobile": "9100000008", "first_name": "Hank", "last_name": "Das", "email": "hank@test.twm"},
    {"mobile": "9100000009", "first_name": "Iris", "last_name": "Menon", "email": "iris@test.twm"},
    {"mobile": "9100000010", "first_name": "Jack", "last_name": "Verma", "email": "jack@test.twm"},
]

PASSWORD = "TestPass@123"


# ── Helpers ───────────────────────────────────────────────────────────────────

def green(msg): print(f"\033[92m✓ {msg}\033[0m")
def yellow(msg): print(f"\033[93m~ {msg}\033[0m")
def red(msg): print(f"\033[91m✗ {msg}\033[0m")


def get_or_create_user(mobile, first_name, last_name, email):
    user = User.objects.filter(mobile=mobile).first()
    if user:
        yellow(f"User exists: {mobile} ({first_name} {last_name})")
        return user, False
    user = User.objects.create_user(
        mobile=mobile,
        password=PASSWORD,
        first_name=first_name,
        last_name=last_name,
        email=email,
        is_active=True,
    )
    green(f"Created user: {mobile} ({first_name} {last_name})")
    return user, True


def top_up_wallet(user, amount, note="Seed top-up"):
    """Credit the user's main wallet."""
    try:
        WalletService.credit_main_wallet(
            user=user,
            amount=Decimal(str(amount)),
            source_type="ADMIN_CREDIT",
            reference_id=f"SEED-{uuid4().hex[:8].upper()}",
        )
        green(f"  Topped up ₹{amount} for {user.first_name}")
    except Exception as e:
        red(f"  Wallet top-up failed for {user.first_name}: {e}")


def do_purchase(user, product, sponsor, tag):
    """Execute a wallet-funded purchase."""
    cref = f"SEED-{uuid4().hex[:8].upper()}"
    try:
        order, distributor, _, _ = execute_purchase(
            user=user,
            product=product,
            sponsor_distributor=sponsor,
            client_reference_id=cref,
            amount=product.base_cost,
            payment_method="main_wallet",
        )
        order.payment_method = "main_wallet"
        order.save(update_fields=["payment_method"])
        green(f"  [{tag}] Purchase OK — dist={distributor.distributor_code} order={order.reference_id}")
        return distributor
    except Exception as e:
        red(f"  [{tag}] Purchase FAILED: {e}")
        return None


def do_pending_payment_order(user, product, sponsor, payment_method, ref_number, tag):
    """Create a PAYMENT_REVIEW order (QR/bank)."""
    cref = f"SEED-{uuid4().hex[:8].upper()}"
    try:
        order = create_pending_payment_order(
            user=user,
            product=product,
            sponsor_distributor=sponsor,
            client_reference_id=cref,
            payment_method=payment_method,
            qr_reference=ref_number,
            amount=product.base_cost,
        )
        green(f"  [{tag}] PAYMENT_REVIEW order created: {order.reference_id} ref={ref_number}")
        return order
    except Exception as e:
        red(f"  [{tag}] Pending order FAILED: {e}")
        return None


def seed_qr_config():
    config = QRConfig.objects.filter(is_active=True).first()
    if not config:
        QRConfig.objects.create(
            bank_name="State Bank of India",
            bank_account_number="00112233445566",
            bank_ifsc_code="SBIN0001234",
            bank_account_holder_name="TrueWave MLM Pvt Ltd",
            upi_id="truewave@sbi",
            payment_instructions=(
                "1. Transfer the exact amount to the bank/UPI below.\n"
                "2. Note your UTR/transaction reference number.\n"
                "3. Enter the reference number during checkout.\n"
                "4. Admin will verify and activate your order within 24 hours."
            ),
            enable_qr_scan=True,
            enable_bank_transfer=True,
            enable_phonepe=True,
            enable_razorpay=True,
            is_active=True,
        )
        green("QRConfig seeded (SBI bank + UPI + Razorpay)")
        return

    config.bank_name = "State Bank of India"
    config.bank_account_number = "00112233445566"
    config.bank_ifsc_code = "SBIN0001234"
    config.bank_account_holder_name = "TrueWave MLM Pvt Ltd"
    config.upi_id = "truewave@sbi"
    config.payment_instructions = (
        "1. Transfer the exact amount to the bank/UPI below.\n"
        "2. Note your UTR/transaction reference number.\n"
        "3. Enter the reference number during checkout.\n"
        "4. Admin will verify and activate your order within 24 hours."
    )
    config.enable_qr_scan = True
    config.enable_bank_transfer = True
    config.enable_phonepe = True
    config.enable_razorpay = True
    config.is_active = True
    config.save(update_fields=[
        "bank_name",
        "bank_account_number",
        "bank_ifsc_code",
        "bank_account_holder_name",
        "upi_id",
        "payment_instructions",
        "enable_qr_scan",
        "enable_bank_transfer",
        "enable_phonepe",
        "enable_razorpay",
        "is_active",
    ])
    green("QRConfig updated (SBI bank + UPI + Razorpay)")


def seed_support_tickets(users):
    if SupportTicket.objects.exists():
        yellow("Support tickets already exist, skipping")
        return
    samples = [
        {
            "user": users[0],
            "subject": "Wallet balance not credited",
            "description": "I made a payment 3 days ago but my wallet has not been credited yet. Please check.",
            "category": "payment",
            "priority": "high",
            "status": "open",
        },
        {
            "user": users[1],
            "subject": "KYC document rejected — need help",
            "description": "My Aadhaar was rejected. The image quality was fine on my device. Please re-review.",
            "category": "kyc",
            "priority": "medium",
            "status": "in_progress",
        },
        {
            "user": users[2],
            "subject": "Order not received",
            "description": "My Goa trip order was placed 2 weeks ago but I have not received any confirmation.",
            "category": "order",
            "priority": "urgent",
            "status": "open",
        },
        {
            "user": users[3],
            "subject": "Cannot login to account",
            "description": "Getting OTP issues. Please reset my account access.",
            "category": "technical",
            "priority": "high",
            "status": "resolved",
        },
        {
            "user": users[4],
            "subject": "Referral bonus not showing",
            "description": "I referred 3 people last month. The sponsor income is not showing in my dashboard.",
            "category": "account",
            "priority": "low",
            "status": "open",
        },
    ]
    for i, s in enumerate(samples):
        ticket_number = f"TKT-{timezone.now().strftime('%y%m%d')}-{str(i+1).zfill(4)}"
        ticket = SupportTicket.objects.create(
            user=s["user"],
            ticket_number=ticket_number,
            subject=s["subject"],
            description=s["description"],
            category=s["category"],
            priority=s["priority"],
            status=s["status"],
        )
        if s["status"] in ("resolved",):
            ticket.resolved_at = timezone.now()
            ticket.save(update_fields=["resolved_at"])
        # Add a sample user message
        SupportTicketMessage.objects.create(
            ticket=ticket,
            sender=s["user"],
            message=s["description"],
            is_internal=False,
        )
        green(f"  Ticket: [{ticket_number}] {s['subject']}")
    green("5 support tickets seeded")


def main():
    print("\n" + "="*60)
    print("  TrueWave Test Data Seed Script")
    print("="*60 + "\n")

    # 1. QR Config
    print("→ Seeding QR Config…")
    seed_qr_config()
    print()

    # 2. Create test users
    print("→ Creating test users…")
    users = []
    for u in TEST_USERS:
        user, _ = get_or_create_user(**u)
        users.append(user)
    print()

    # 3. Get the main product and admin user
    product = Product.objects.filter(id=MAIN_PRODUCT_ID).first()
    if not product:
        red(f"Main product {MAIN_PRODUCT_ID} not found. Aborting.")
        return
    print(f"Using product: {product.name} (₹{product.base_cost})\n")

    admin_user = User.objects.filter(is_superuser=True).first()

    # 4. Top up wallets for wallet-payment purchases
    print("→ Topping up wallets…")
    for user in users:
        top_up_wallet(user, 20000, "Seed test balance")
    print()

    # 5. Create root distributor for admin directly (no execute_purchase, no direct incentive needed)
    #    This acts as the company root — every network needs a root sponsor.
    print("→ Creating root sponsor distributor for admin (direct, no purchase pipeline)…")
    root_dist = DistributorID.objects.filter(user=admin_user, product=product).first()
    if not root_dist:
        try:
            root_dist = create_distributor_id(admin_user, product, None)
            green(f"  Root distributor created: {root_dist.distributor_code}")
        except Exception as e:
            import traceback; traceback.print_exc()
            red(f"  Root distributor creation failed: {e}")
    else:
        print(f"  ~ Root distributor already exists: {root_dist.distributor_code}")
    if not root_dist:
        red("Could not create root distributor. Skipping purchase seeding.")
    print()

    # 6. Purchases — build a small network
    print("→ Seeding purchases (wallet payments)…")

    # Alice purchases first — under admin root
    d_alice = do_purchase(users[0], product, root_dist, "Alice under admin") if root_dist else None

    # Bob under Alice
    d_bob = do_purchase(users[1], product, d_alice, "Bob under Alice") if d_alice else None

    # Carol under Alice
    d_carol = do_purchase(users[2], product, d_alice, "Carol under Alice") if d_alice else None

    # David under Bob
    d_david = do_purchase(users[3], product, d_bob, "David under Bob") if d_bob else None

    # Eve under Bob
    d_eve = do_purchase(users[4], product, d_bob, "Eve under Bob") if d_bob else None

    # Frank under Carol
    d_frank = do_purchase(users[5], product, d_carol, "Frank under Carol") if d_carol else None

    # Grace under Carol
    d_grace = do_purchase(users[6], product, d_carol, "Grace under Carol") if d_carol else None

    # Hank under David
    d_hank = do_purchase(users[7], product, d_david, "Hank under David") if d_david else None

    # Iris under Alice
    d_iris = do_purchase(users[8], product, d_alice, "Iris under Alice") if d_alice else None

    # Jack under Frank
    d_jack = do_purchase(users[9], product, d_frank, "Jack under Frank") if d_frank else None

    print()

    # 7. PAYMENT_REVIEW orders (QR / bank transfer)
    print("→ Seeding PAYMENT_REVIEW (pending) orders…")

    # QR scan pending — Alice buying a second product
    do_pending_payment_order(
        users[0], product, d_alice,
        payment_method="qr_scan",
        ref_number="UTR123456789ALICE",
        tag="Alice QR pending",
    )

    # Bank transfer pending — Bob
    do_pending_payment_order(
        users[1], product, d_bob,
        payment_method="bank_transfer",
        ref_number="NEFT202412010001BOB",
        tag="Bob Bank pending",
    )

    # PhonePe pending — Carol
    do_pending_payment_order(
        users[2], product, d_carol,
        payment_method="phonepe",
        ref_number="PHONEPE9988CAROL",
        tag="Carol PhonePe pending",
    )
    print()

    # 7. Support tickets
    print("→ Seeding support tickets…")
    seed_support_tickets(users)
    print()

    # 8. TWM Coins grant (via wallet service)
    print("→ Granting TWM coins (voucher wallet) to selected users…")
    for user in users[:5]:
        try:
            WalletService.credit_voucher_wallet(
                user=user,
                amount=Decimal("500"),
                source_type="TWM_COINS_PURCHASE",
                reference_id=f"SEED-COINS-{uuid4().hex[:8].upper()}",
            )
            green(f"  Granted 500 TWM coins to {user.first_name}")
        except Exception as e:
            red(f"  TWM coins grant failed for {user.first_name}: {e}")
    print()

    # 9. Summary
    print("="*60)
    print("  Seed Complete! Summary:")
    print("="*60)
    from apps.business.orders.models import Order
    from apps.business.wallet.models import Wallet
    print(f"  Users (test):        {User.objects.filter(mobile__startswith='91000000').count()}")
    print(f"  DistributorIDs:      {DistributorID.objects.count()}")
    print(f"  Orders (COMPLETED):  {Order.objects.filter(status='COMPLETED').count()}")
    print(f"  Orders (PAYMENT_REVIEW): {Order.objects.filter(status='PAYMENT_REVIEW').count()}")
    print(f"  Wallets:             {Wallet.objects.count()}")
    print(f"  Support tickets:     {SupportTicket.objects.count()}")
    print()
    print("  Login credentials for test users:")
    print(f"    Mobile: 9100000001–9100000010")
    print(f"    Password: {PASSWORD}")
    print()
    print("  Admin:")
    print(f"    Mobile/Email: mdmconsultant@gmail.com or admin@example.com")
    print()
    print("  Pending orders to approve/reject in Admin → Orders:")
    for o in Order.objects.filter(status='PAYMENT_REVIEW').select_related('user'):
        print(f"    [{o.payment_method}] {o.reference_id} — ref: {o.qr_reference} — user: {o.user.first_name}")
    print()


if __name__ == "__main__":
    main()
