import asyncio
from src.database import engine, Base
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.future import select

# Імпорт моделей
from src.manufacturer.models import Manufacturer
from src.address.models import Zone, City
from src.store.models import Store, StorePhoto, StoreAddress, ProductStore
from src.user.models import UserRole, User
from src.customer.models import Customer, AuthTypeEnum
from src.review.models import (
    StoreReview, ManufacturerReview,
    ServiceReview, ProductReview, ReviewStatusEnum
)
from src.category.models import Category, CategoryStatus
from src.product.models import Product, ProductStatus, ProductAttribute, ProductImage, ProductCategory
from src.security import hash_password


async def create_test_data(session: AsyncSession):
    result = await session.execute(select(Manufacturer))
    if result.scalars().first():
        print("Тестові дані вже існують.")
        return

    print("Створюємо тестові дані...")

    # Виробники
    m1 = Manufacturer(name="Test Manufacturer 1", rating=4.5)
    m2 = Manufacturer(name="Test Manufacturer 2", rating=3.8)

    # Зони, міста
    zone1 = Zone(name="Zone A")
    zone2 = Zone(name="Zone B")

    city1 = City(name="City One", area_text="Area 1", zone=zone1)
    city2 = City(name="City Two", area_text="Area 2", zone=zone2)

    # Магазини без ProductStore поки що
    store1 = Store(
        name="Test Store 1",
        rating=5,
        seo_keyword="test-store-1",
        meta_title="Test Store 1 Title",
        meta_description="Description for store 1",
        meta_keyword="test,store1",
        logo="logo1.png",
        addresses=[
            StoreAddress(
                address="123 Test St",
                phone_number="+123456789",
                schedule="9-18",
                city=city1,
                zone=zone1,
            )
        ],
        photos=[
            StorePhoto(image="photo1.png"),
            StorePhoto(image="photo2.png"),
        ],
    )

    store2 = Store(name="Test Store 2", rating=4)

    # Ролі користувачів
    role_admin = UserRole(name="admin")
    role_user = UserRole(name="user")

    # Користувачі
    user1 = User(
        name="Admin User",
        login="admin",
        phone="+380123456789",
        password=hash_password("adminpassword123"),
        logo="admin_logo.png",
        role=role_admin
    )

    user2 = User(
        name="Regular User",
        login="user",
        phone="+380987654321",
        password=hash_password("userpassword123"),
        logo="user_logo.png",
        role=role_user
    )

    # Клієнти
    customer1 = Customer(
        name="Test Customer 1",
        phone="380991112233",
        password=hash_password("custpass123"),
        comment="VIP client",
        logo="cust1.png",
        ip="192.168.0.11",
        auth_type=AuthTypeEnum.phone
    )

    customer2 = Customer(
        name="Google User",
        phone="380992223344",
        password=hash_password("googlepass456"),
        logo="cust2.png",
        ip="192.168.0.22",
        auth_type=AuthTypeEnum.google,
        banned=True
    )

    # Категорії (порядок важливий)
    cat_moto = Category(name="Для мотоцикліста", status=CategoryStatus.ENABLED.value)

    cat_accessories = Category(name="Аксесуари", parent=cat_moto, status=CategoryStatus.ENABLED.value)
    cat_backpacks = Category(name="Рюкзаки", parent=cat_accessories, status=CategoryStatus.ENABLED.value)
    cat_balaclavas = Category(name="Балаклави та коміри", parent=cat_accessories, status=CategoryStatus.ENABLED.value)
    cat_knee_pads = Category(name="Накладки на коліна", parent=cat_accessories, status=CategoryStatus.ENABLED.value)
    cat_bestsellers = Category(name="Бестселери", parent=cat_moto, status=CategoryStatus.ENABLED.value)

    cat_footwear = Category(name="Взуття", parent=cat_moto, status=CategoryStatus.ENABLED.value)
    cat_footwear_short = Category(name="Короткі", parent=cat_footwear, status=CategoryStatus.ENABLED.value)
    cat_footwear_adventure = Category(name="Пригоди", parent=cat_footwear, status=CategoryStatus.ENABLED.value)

    cat_for_bike = Category(name="Для мотоцикла", status=CategoryStatus.ENABLED.value)
    cat_for_bike_accessories = Category(name="Аксесуари", parent=cat_for_bike, status=CategoryStatus.ENABLED.value)

    # Додаємо основні об'єкти, щоб отримати id для зв’язків
    session.add_all([
        m1, m2,
        zone1, zone2,
        city1, city2,
        store1, store2,
        role_admin, role_user,
        user1, user2,
        customer1, customer2,
        cat_moto, cat_accessories, cat_backpacks, cat_balaclavas, cat_knee_pads, cat_bestsellers,
        cat_footwear, cat_footwear_short, cat_footwear_adventure,
        cat_for_bike, cat_for_bike_accessories,
    ])

    await session.flush()  # Флашимо, щоб отримати id

    # Продукт
    product_backpack = Product(
        name="Рюкзак мотоцикліста SHAD E-83",
        description="Зручний мото-рюкзак для щоденного використання",
        seo_keyword="рюкзак-shad-e83",
        meta_title="SHAD E-83 рюкзак",
        meta_description="SHAD E-83 — зручний рюкзак для мотоциклістів",
        meta_keyword="рюкзак, SHAD, мотоцикліст",
        image="products/shad-e83.jpg",
        status=ProductStatus.ON,
        price=1899.00,
        model="SHAD-E83",
        manufacturer=m1,
        rating=4.8,
        viewed=53,
    )

    session.add(product_backpack)
    await session.flush()  # Отримаємо product_backpack.product_id

    # Прив'язка продукту до категорії
    product_backpack_category = ProductCategory(product=product_backpack, category=cat_backpacks)

    # Зображення продукту
    product_backpack_image1 = ProductImage(product=product_backpack, image="products/shad-e83-front.jpg", sort_order=1)
    product_backpack_image2 = ProductImage(product=product_backpack, image="products/shad-e83-side.jpg", sort_order=2)

    # Атрибути продукту
    product_backpack_attr1 = ProductAttribute(product=product_backpack, group_name="Основні характеристики", name="Обʼєм", value="25 л", sort_order=1)
    product_backpack_attr2 = ProductAttribute(product=product_backpack, group_name="Основні характеристики", name="Матеріал", value="Поліестер", sort_order=2)

    # Тепер додаємо зв'язок ProductStore із ціною і посиланням на збережений продукт і магазин
    ps1 = ProductStore(product=product_backpack, store=store1, price=100.0)
    ps2 = ProductStore(product=product_backpack, store=store1, price=200.0)

    # Відгуки
    store_review = StoreReview(store=store1, customer=customer1, text="Great store with awesome prices!", rating=5, ip="192.168.0.11", status=ReviewStatusEnum.approved)
    manufacturer_review = ManufacturerReview(manufacturer=m1, customer=customer2, text="Products are high-quality and reliable.", rating=4, ip="192.168.0.22", status=ReviewStatusEnum.approved)
    service_review = ServiceReview(customer=customer1, text="Quick delivery and excellent service!", rating=5, ip="192.168.0.11", status=ReviewStatusEnum.new)
    product_review = ProductReview(manufacturer=m1, product=product_backpack, customer=customer2, text="The product matches the description perfectly.", rating=5, ip="192.168.0.22", status=ReviewStatusEnum.approved)

    session.add_all([
        product_backpack_category,
        product_backpack_image1, product_backpack_image2,
        product_backpack_attr1, product_backpack_attr2,
        ps1, ps2,
        store_review, manufacturer_review, service_review, product_review,
    ])

    await session.commit()
    print("✅ Тестові дані успішно створено.")


async def init_db():
    async with engine.begin() as conn:
        await conn.run_sync(Base.metadata.create_all)

    async with AsyncSession(engine) as session:
        await create_test_data(session)


if __name__ == "__main__":
    loop = asyncio.new_event_loop()
    asyncio.set_event_loop(loop)
    try:
        loop.run_until_complete(init_db())
    finally:
        loop.run_until_complete(engine.dispose())
        loop.close()
