from fastapi import FastAPI, APIRouter, HTTPException, Depends, status, Query, Response
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
from fastapi.responses import StreamingResponse
from dotenv import load_dotenv
from starlette.middleware.cors import CORSMiddleware
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select, func, and_, or_, desc, asc
from sqlalchemy.orm import selectinload
import os
import logging
from pathlib import Path
from pydantic import BaseModel, Field, EmailStr, ConfigDict
from typing import List, Optional, Dict, Any
import uuid
from datetime import datetime, timezone, timedelta
import bcrypt
import jwt
import io
import csv
from reportlab.lib import colors
from reportlab.lib.pagesizes import letter, A4
from reportlab.platypus import SimpleDocTemplate, Table, TableStyle, Paragraph, Spacer
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import inch

from database import get_db, init_db, AsyncSessionLocal
from models import (
    User, Product, Service, CartItem, Order, OrderItem, OrderStatusHistory,
    Review, Booking, Contact, InventoryLog, Category, SalesReport,
    OrderStatus, UserRole, Base
)

ROOT_DIR = Path(__file__).parent
load_dotenv(ROOT_DIR / '.env')

# JWT Configuration
SECRET_KEY = os.environ.get('JWT_SECRET', 'techzone-super-secret-key-2024-production')
ALGORITHM = "HS256"
ACCESS_TOKEN_EXPIRE_HOURS = 24

# Create the main app
app = FastAPI(title="TechZone API", version="2.0.0")

# Create a router with the /api prefix
api_router = APIRouter(prefix="/api")

security = HTTPBearer()

# ================== PYDANTIC MODELS ==================

class UserCreate(BaseModel):
    email: EmailStr
    name: str
    password: str

class UserLogin(BaseModel):
    email: EmailStr
    password: str

class TokenResponse(BaseModel):
    access_token: str
    token_type: str = "bearer"
    user: dict

class ProductCreate(BaseModel):
    name: str
    description: str
    price: float
    category: str
    image_url: str
    stock: int = 10
    low_stock_threshold: int = 5
    brand: str = ""
    specs: dict = {}

class ProductUpdate(BaseModel):
    name: Optional[str] = None
    description: Optional[str] = None
    price: Optional[float] = None
    category: Optional[str] = None
    image_url: Optional[str] = None
    stock: Optional[int] = None
    low_stock_threshold: Optional[int] = None
    brand: Optional[str] = None
    specs: Optional[dict] = None
    is_active: Optional[bool] = None

class ServiceCreate(BaseModel):
    name: str
    description: str
    price: float
    duration: str
    image_url: str
    category: str

class ServiceUpdate(BaseModel):
    name: Optional[str] = None
    description: Optional[str] = None
    price: Optional[float] = None
    duration: Optional[str] = None
    image_url: Optional[str] = None
    category: Optional[str] = None
    is_active: Optional[bool] = None

class CartItemCreate(BaseModel):
    product_id: str
    quantity: int = 1

class OrderCreate(BaseModel):
    shipping_address: dict = {}
    notes: str = ""

class OrderStatusUpdate(BaseModel):
    status: str
    notes: str = ""
    tracking_number: Optional[str] = None

class ReviewCreate(BaseModel):
    product_id: Optional[str] = None
    service_id: Optional[str] = None
    rating: int
    title: str = ""
    comment: str = ""

class BookingCreate(BaseModel):
    service_id: str
    name: str
    email: EmailStr
    phone: str
    preferred_date: str
    notes: str = ""

class ContactCreate(BaseModel):
    name: str
    email: EmailStr
    subject: str
    message: str

class InventoryAdjust(BaseModel):
    quantity_change: int
    notes: str = ""

# ================== HELPERS ==================

def hash_password(password: str) -> str:
    return bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt()).decode('utf-8')

def verify_password(password: str, hashed: str) -> bool:
    return bcrypt.checkpw(password.encode('utf-8'), hashed.encode('utf-8'))

def create_access_token(data: dict) -> str:
    to_encode = data.copy()
    expire = datetime.now(timezone.utc) + timedelta(hours=ACCESS_TOKEN_EXPIRE_HOURS)
    to_encode.update({"exp": expire})
    return jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)

async def get_current_user(credentials: HTTPAuthorizationCredentials = Depends(security), db: AsyncSession = Depends(get_db)):
    try:
        payload = jwt.decode(credentials.credentials, SECRET_KEY, algorithms=[ALGORITHM])
        user_id = payload.get("sub")
        if user_id is None:
            raise HTTPException(status_code=401, detail="Invalid token")
        result = await db.execute(select(User).where(User.id == user_id))
        user = result.scalar_one_or_none()
        if user is None:
            raise HTTPException(status_code=401, detail="User not found")
        return user
    except jwt.ExpiredSignatureError:
        raise HTTPException(status_code=401, detail="Token expired")
    except jwt.InvalidTokenError:
        raise HTTPException(status_code=401, detail="Invalid token")

async def get_admin_user(user: User = Depends(get_current_user)):
    if user.role != UserRole.ADMIN:
        raise HTTPException(status_code=403, detail="Admin access required")
    return user

async def get_optional_user(credentials: Optional[HTTPAuthorizationCredentials] = Depends(HTTPBearer(auto_error=False)), db: AsyncSession = Depends(get_db)):
    if credentials is None:
        return None
    try:
        payload = jwt.decode(credentials.credentials, SECRET_KEY, algorithms=[ALGORITHM])
        user_id = payload.get("sub")
        if user_id:
            result = await db.execute(select(User).where(User.id == user_id))
            return result.scalar_one_or_none()
    except:
        pass
    return None

def user_to_dict(user: User) -> dict:
    return {
        "id": user.id,
        "email": user.email,
        "name": user.name,
        "role": user.role.value if user.role else "user",
        "created_at": user.created_at.isoformat() if user.created_at else None
    }

def product_to_dict(product: Product, include_reviews: bool = False) -> dict:
    data = {
        "id": product.id,
        "name": product.name,
        "description": product.description,
        "price": product.price,
        "category": product.category,
        "image_url": product.image_url,
        "stock": product.stock,
        "low_stock_threshold": product.low_stock_threshold,
        "brand": product.brand,
        "specs": product.specs or {},
        "is_active": product.is_active,
        "created_at": product.created_at.isoformat() if product.created_at else None
    }
    if include_reviews and product.reviews:
        data["reviews"] = [review_to_dict(r) for r in product.reviews]
        data["average_rating"] = sum(r.rating for r in product.reviews) / len(product.reviews) if product.reviews else 0
        data["review_count"] = len(product.reviews)
    return data

def service_to_dict(service: Service, include_reviews: bool = False) -> dict:
    data = {
        "id": service.id,
        "name": service.name,
        "description": service.description,
        "price": service.price,
        "duration": service.duration,
        "image_url": service.image_url,
        "category": service.category,
        "is_active": service.is_active,
        "created_at": service.created_at.isoformat() if service.created_at else None
    }
    if include_reviews and service.reviews:
        data["reviews"] = [review_to_dict(r) for r in service.reviews]
        data["average_rating"] = sum(r.rating for r in service.reviews) / len(service.reviews) if service.reviews else 0
        data["review_count"] = len(service.reviews)
    return data

def order_to_dict(order: Order) -> dict:
    return {
        "id": order.id,
        "user_id": order.user_id,
        "status": order.status.value if order.status else "pending",
        "subtotal": order.subtotal,
        "tax": order.tax,
        "shipping": order.shipping,
        "total": order.total,
        "shipping_address": order.shipping_address or {},
        "notes": order.notes,
        "tracking_number": order.tracking_number,
        "created_at": order.created_at.isoformat() if order.created_at else None,
        "updated_at": order.updated_at.isoformat() if order.updated_at else None,
        "items": [order_item_to_dict(item) for item in order.items] if order.items else [],
        "status_history": [status_history_to_dict(h) for h in order.status_history] if order.status_history else []
    }

def order_item_to_dict(item: OrderItem) -> dict:
    return {
        "id": item.id,
        "product_id": item.product_id,
        "product_name": item.product_name,
        "product_image": item.product_image,
        "quantity": item.quantity,
        "price": item.price
    }

def status_history_to_dict(history: OrderStatusHistory) -> dict:
    return {
        "id": history.id,
        "status": history.status.value if history.status else None,
        "notes": history.notes,
        "created_at": history.created_at.isoformat() if history.created_at else None
    }

def review_to_dict(review: Review) -> dict:
    return {
        "id": review.id,
        "user_id": review.user_id,
        "user_name": review.user.name if review.user else "Anonymous",
        "product_id": review.product_id,
        "service_id": review.service_id,
        "rating": review.rating,
        "title": review.title,
        "comment": review.comment,
        "is_verified_purchase": review.is_verified_purchase,
        "created_at": review.created_at.isoformat() if review.created_at else None
    }

def booking_to_dict(booking: Booking) -> dict:
    return {
        "id": booking.id,
        "service_id": booking.service_id,
        "service_name": booking.service_name,
        "name": booking.name,
        "email": booking.email,
        "phone": booking.phone,
        "preferred_date": booking.preferred_date,
        "notes": booking.notes,
        "status": booking.status,
        "created_at": booking.created_at.isoformat() if booking.created_at else None
    }

# ================== AUTH ROUTES ==================

@api_router.post("/auth/register", response_model=TokenResponse)
async def register(user_data: UserCreate, db: AsyncSession = Depends(get_db)):
    result = await db.execute(select(User).where(User.email == user_data.email))
    if result.scalar_one_or_none():
        raise HTTPException(status_code=400, detail="Email already registered")
    
    user = User(
        email=user_data.email,
        name=user_data.name,
        password=hash_password(user_data.password),
        role=UserRole.USER
    )
    db.add(user)
    await db.commit()
    await db.refresh(user)
    
    token = create_access_token({"sub": user.id})
    return TokenResponse(access_token=token, user=user_to_dict(user))

@api_router.post("/auth/login", response_model=TokenResponse)
async def login(credentials: UserLogin, db: AsyncSession = Depends(get_db)):
    result = await db.execute(select(User).where(User.email == credentials.email))
    user = result.scalar_one_or_none()
    if not user or not verify_password(credentials.password, user.password):
        raise HTTPException(status_code=401, detail="Invalid credentials")
    
    token = create_access_token({"sub": user.id})
    return TokenResponse(access_token=token, user=user_to_dict(user))

@api_router.get("/auth/me")
async def get_me(user: User = Depends(get_current_user)):
    return user_to_dict(user)

# ================== PRODUCTS ROUTES ==================

@api_router.get("/products")
async def get_products(
    category: Optional[str] = None,
    search: Optional[str] = None,
    min_price: Optional[float] = None,
    max_price: Optional[float] = None,
    in_stock: Optional[bool] = None,
    db: AsyncSession = Depends(get_db)
):
    query = select(Product).where(Product.is_active == True)
    
    if category and category != "all":
        query = query.where(Product.category == category)
    if search:
        query = query.where(
            or_(
                Product.name.ilike(f"%{search}%"),
                Product.description.ilike(f"%{search}%"),
                Product.brand.ilike(f"%{search}%")
            )
        )
    if min_price is not None:
        query = query.where(Product.price >= min_price)
    if max_price is not None:
        query = query.where(Product.price <= max_price)
    if in_stock:
        query = query.where(Product.stock > 0)
    
    query = query.options(selectinload(Product.reviews).selectinload(Review.user))
    result = await db.execute(query)
    products = result.scalars().all()
    return [product_to_dict(p, include_reviews=True) for p in products]

@api_router.get("/products/{product_id}")
async def get_product(product_id: str, db: AsyncSession = Depends(get_db)):
    result = await db.execute(
        select(Product)
        .where(Product.id == product_id)
        .options(selectinload(Product.reviews).selectinload(Review.user))
    )
    product = result.scalar_one_or_none()
    if not product:
        raise HTTPException(status_code=404, detail="Product not found")
    return product_to_dict(product, include_reviews=True)

@api_router.get("/products/categories/list")
async def get_product_categories(db: AsyncSession = Depends(get_db)):
    result = await db.execute(select(Product.category).distinct())
    categories = [row[0] for row in result.fetchall()]
    return categories

# ================== SERVICES ROUTES ==================

@api_router.get("/services")
async def get_services(category: Optional[str] = None, db: AsyncSession = Depends(get_db)):
    query = select(Service).where(Service.is_active == True)
    if category and category != "all":
        query = query.where(Service.category == category)
    query = query.options(selectinload(Service.reviews).selectinload(Review.user))
    result = await db.execute(query)
    services = result.scalars().all()
    return [service_to_dict(s, include_reviews=True) for s in services]

@api_router.get("/services/{service_id}")
async def get_service(service_id: str, db: AsyncSession = Depends(get_db)):
    result = await db.execute(
        select(Service)
        .where(Service.id == service_id)
        .options(selectinload(Service.reviews).selectinload(Review.user))
    )
    service = result.scalar_one_or_none()
    if not service:
        raise HTTPException(status_code=404, detail="Service not found")
    return service_to_dict(service, include_reviews=True)

@api_router.post("/services/book")
async def book_service(
    booking_data: BookingCreate,
    user: Optional[User] = Depends(get_optional_user),
    db: AsyncSession = Depends(get_db)
):
    result = await db.execute(select(Service).where(Service.id == booking_data.service_id))
    service = result.scalar_one_or_none()
    if not service:
        raise HTTPException(status_code=404, detail="Service not found")
    
    booking = Booking(
        service_id=booking_data.service_id,
        user_id=user.id if user else None,
        name=booking_data.name,
        email=booking_data.email,
        phone=booking_data.phone,
        preferred_date=booking_data.preferred_date,
        notes=booking_data.notes,
        service_name=service.name
    )
    db.add(booking)
    await db.commit()
    return {"message": "Booking created successfully", "booking_id": booking.id}

# ================== CART ROUTES ==================

@api_router.get("/cart")
async def get_cart(user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db)):
    result = await db.execute(
        select(CartItem)
        .where(CartItem.user_id == user.id)
        .options(selectinload(CartItem.product))
    )
    cart_items = result.scalars().all()
    return [{
        "id": item.id,
        "product_id": item.product_id,
        "quantity": item.quantity,
        "product": product_to_dict(item.product) if item.product else None
    } for item in cart_items]

@api_router.post("/cart/add")
async def add_to_cart(item: CartItemCreate, user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db)):
    result = await db.execute(select(Product).where(Product.id == item.product_id))
    product = result.scalar_one_or_none()
    if not product:
        raise HTTPException(status_code=404, detail="Product not found")
    
    result = await db.execute(
        select(CartItem).where(
            and_(CartItem.user_id == user.id, CartItem.product_id == item.product_id)
        )
    )
    existing = result.scalar_one_or_none()
    
    if existing:
        existing.quantity += item.quantity
    else:
        cart_item = CartItem(user_id=user.id, product_id=item.product_id, quantity=item.quantity)
        db.add(cart_item)
    
    await db.commit()
    return {"message": "Item added to cart"}

@api_router.put("/cart/{item_id}")
async def update_cart_item(item_id: str, quantity: int = Query(...), user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db)):
    result = await db.execute(
        select(CartItem).where(and_(CartItem.id == item_id, CartItem.user_id == user.id))
    )
    item = result.scalar_one_or_none()
    if not item:
        raise HTTPException(status_code=404, detail="Cart item not found")
    
    if quantity <= 0:
        await db.delete(item)
    else:
        item.quantity = quantity
    
    await db.commit()
    return {"message": "Cart updated"}

@api_router.delete("/cart/{item_id}")
async def remove_from_cart(item_id: str, user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db)):
    result = await db.execute(
        select(CartItem).where(and_(CartItem.id == item_id, CartItem.user_id == user.id))
    )
    item = result.scalar_one_or_none()
    if item:
        await db.delete(item)
        await db.commit()
    return {"message": "Item removed from cart"}

@api_router.delete("/cart")
async def clear_cart(user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db)):
    await db.execute(
        CartItem.__table__.delete().where(CartItem.user_id == user.id)
    )
    await db.commit()
    return {"message": "Cart cleared"}

# ================== ORDERS ROUTES ==================

@api_router.post("/orders")
async def create_order(order_data: OrderCreate, user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db)):
    # Get cart items
    result = await db.execute(
        select(CartItem)
        .where(CartItem.user_id == user.id)
        .options(selectinload(CartItem.product))
    )
    cart_items = result.scalars().all()
    
    if not cart_items:
        raise HTTPException(status_code=400, detail="Cart is empty")
    
    # Calculate totals
    subtotal = sum(item.product.price * item.quantity for item in cart_items)
    tax = subtotal * 0.08
    shipping = 0 if subtotal > 100 else 9.99
    total = subtotal + tax + shipping
    
    # Create order
    order = Order(
        user_id=user.id,
        status=OrderStatus.PENDING,
        subtotal=subtotal,
        tax=tax,
        shipping=shipping,
        total=total,
        shipping_address=order_data.shipping_address,
        notes=order_data.notes
    )
    db.add(order)
    await db.flush()
    
    # Create order items and update inventory
    for cart_item in cart_items:
        product = cart_item.product
        order_item = OrderItem(
            order_id=order.id,
            product_id=product.id,
            quantity=cart_item.quantity,
            price=product.price,
            product_name=product.name,
            product_image=product.image_url
        )
        db.add(order_item)
        
        # Update stock
        previous_stock = product.stock
        product.stock = max(0, product.stock - cart_item.quantity)
        
        # Log inventory change
        inv_log = InventoryLog(
            product_id=product.id,
            action="sale",
            quantity_change=-cart_item.quantity,
            previous_stock=previous_stock,
            new_stock=product.stock,
            notes=f"Order {order.id}",
            created_by=user.id
        )
        db.add(inv_log)
    
    # Add status history
    status_history = OrderStatusHistory(
        order_id=order.id,
        status=OrderStatus.PENDING,
        notes="Order placed",
        created_by=user.id
    )
    db.add(status_history)
    
    # Clear cart
    await db.execute(CartItem.__table__.delete().where(CartItem.user_id == user.id))
    
    await db.commit()
    await db.refresh(order)
    
    return {"message": "Order created successfully", "order_id": order.id}

@api_router.get("/orders")
async def get_orders(user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db)):
    result = await db.execute(
        select(Order)
        .where(Order.user_id == user.id)
        .options(selectinload(Order.items), selectinload(Order.status_history))
        .order_by(desc(Order.created_at))
    )
    orders = result.scalars().all()
    return [order_to_dict(o) for o in orders]

@api_router.get("/orders/{order_id}")
async def get_order(order_id: str, user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db)):
    result = await db.execute(
        select(Order)
        .where(and_(Order.id == order_id, Order.user_id == user.id))
        .options(selectinload(Order.items), selectinload(Order.status_history))
    )
    order = result.scalar_one_or_none()
    if not order:
        raise HTTPException(status_code=404, detail="Order not found")
    return order_to_dict(order)

# ================== REVIEWS ROUTES ==================

@api_router.post("/reviews")
async def create_review(review_data: ReviewCreate, user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db)):
    if not review_data.product_id and not review_data.service_id:
        raise HTTPException(status_code=400, detail="Product or service ID required")
    
    if review_data.rating < 1 or review_data.rating > 5:
        raise HTTPException(status_code=400, detail="Rating must be between 1 and 5")
    
    # Check for verified purchase
    is_verified = False
    if review_data.product_id:
        result = await db.execute(
            select(OrderItem)
            .join(Order)
            .where(
                and_(
                    Order.user_id == user.id,
                    OrderItem.product_id == review_data.product_id,
                    Order.status.in_([OrderStatus.DELIVERED, OrderStatus.SHIPPED])
                )
            )
        )
        if result.scalar_one_or_none():
            is_verified = True
    
    review = Review(
        user_id=user.id,
        product_id=review_data.product_id,
        service_id=review_data.service_id,
        rating=review_data.rating,
        title=review_data.title,
        comment=review_data.comment,
        is_verified_purchase=is_verified
    )
    db.add(review)
    await db.commit()
    await db.refresh(review)
    
    return {"message": "Review submitted successfully", "review_id": review.id}

@api_router.get("/reviews/product/{product_id}")
async def get_product_reviews(product_id: str, db: AsyncSession = Depends(get_db)):
    result = await db.execute(
        select(Review)
        .where(and_(Review.product_id == product_id, Review.is_approved == True))
        .options(selectinload(Review.user))
        .order_by(desc(Review.created_at))
    )
    reviews = result.scalars().all()
    return [review_to_dict(r) for r in reviews]

@api_router.get("/reviews/service/{service_id}")
async def get_service_reviews(service_id: str, db: AsyncSession = Depends(get_db)):
    result = await db.execute(
        select(Review)
        .where(and_(Review.service_id == service_id, Review.is_approved == True))
        .options(selectinload(Review.user))
        .order_by(desc(Review.created_at))
    )
    reviews = result.scalars().all()
    return [review_to_dict(r) for r in reviews]

# ================== CONTACT ROUTES ==================

@api_router.post("/contact")
async def submit_contact(contact_data: ContactCreate, db: AsyncSession = Depends(get_db)):
    contact = Contact(
        name=contact_data.name,
        email=contact_data.email,
        subject=contact_data.subject,
        message=contact_data.message
    )
    db.add(contact)
    await db.commit()
    return {"message": "Message sent successfully", "id": contact.id}

# ================== ADMIN ROUTES ==================

# Admin - Dashboard Stats
@api_router.get("/admin/dashboard")
async def get_admin_dashboard(user: User = Depends(get_admin_user), db: AsyncSession = Depends(get_db)):
    today = datetime.now(timezone.utc).date()
    month_ago = today - timedelta(days=30)
    
    # Total counts
    products_count = await db.execute(select(func.count(Product.id)))
    services_count = await db.execute(select(func.count(Service.id)))
    users_count = await db.execute(select(func.count(User.id)))
    orders_count = await db.execute(select(func.count(Order.id)))
    
    # Revenue
    total_revenue = await db.execute(select(func.sum(Order.total)))
    monthly_revenue = await db.execute(
        select(func.sum(Order.total))
        .where(Order.created_at >= datetime.combine(month_ago, datetime.min.time()))
    )
    
    # Today's stats
    today_orders = await db.execute(
        select(func.count(Order.id))
        .where(func.date(Order.created_at) == today)
    )
    today_revenue = await db.execute(
        select(func.sum(Order.total))
        .where(func.date(Order.created_at) == today)
    )
    
    # Low stock products - don't use relationships
    low_stock = await db.execute(
        select(Product)
        .where(Product.stock <= Product.low_stock_threshold)
        .where(Product.is_active == True)
    )
    low_stock_list = low_stock.scalars().all()
    low_stock_products = [{
        "id": p.id,
        "name": p.name,
        "stock": p.stock,
        "low_stock_threshold": p.low_stock_threshold,
        "category": p.category
    } for p in low_stock_list]
    
    # Recent orders - load items explicitly
    recent_orders_result = await db.execute(
        select(Order)
        .options(selectinload(Order.items))
        .order_by(desc(Order.created_at))
        .limit(10)
    )
    recent_orders_list = recent_orders_result.scalars().all()
    
    # Pending bookings
    pending_bookings = await db.execute(
        select(func.count(Booking.id))
        .where(Booking.status == "pending")
    )
    
    recent_orders_data = []
    for o in recent_orders_list:
        recent_orders_data.append({
            "id": o.id,
            "status": o.status.value if o.status else "pending",
            "total": o.total,
            "created_at": o.created_at.isoformat() if o.created_at else None,
            "items": [{"id": i.id, "product_name": i.product_name, "quantity": i.quantity} for i in o.items] if o.items else []
        })
    
    return {
        "stats": {
            "total_products": products_count.scalar() or 0,
            "total_services": services_count.scalar() or 0,
            "total_users": users_count.scalar() or 0,
            "total_orders": orders_count.scalar() or 0,
            "total_revenue": total_revenue.scalar() or 0,
            "monthly_revenue": monthly_revenue.scalar() or 0,
            "today_orders": today_orders.scalar() or 0,
            "today_revenue": today_revenue.scalar() or 0,
            "pending_bookings": pending_bookings.scalar() or 0
        },
        "low_stock_products": low_stock_products,
        "recent_orders": recent_orders_data
    }
    
    return {
        "stats": {
            "total_products": products_count.scalar() or 0,
            "total_services": services_count.scalar() or 0,
            "total_users": users_count.scalar() or 0,
            "total_orders": orders_count.scalar() or 0,
            "total_revenue": total_revenue.scalar() or 0,
            "monthly_revenue": monthly_revenue.scalar() or 0,
            "today_orders": today_orders.scalar() or 0,
            "today_revenue": today_revenue.scalar() or 0,
            "pending_bookings": pending_bookings.scalar() or 0
        },
        "low_stock_products": low_stock_products,
        "recent_orders": recent_orders_data
    }

# Admin - Products CRUD
@api_router.get("/admin/products")
async def admin_get_products(
    include_inactive: bool = False,
    user: User = Depends(get_admin_user),
    db: AsyncSession = Depends(get_db)
):
    query = select(Product)
    if not include_inactive:
        query = query.where(Product.is_active == True)
    query = query.order_by(desc(Product.created_at))
    result = await db.execute(query)
    products = result.scalars().all()
    return [product_to_dict(p) for p in products]

@api_router.post("/admin/products")
async def admin_create_product(product_data: ProductCreate, user: User = Depends(get_admin_user), db: AsyncSession = Depends(get_db)):
    product = Product(**product_data.model_dump())
    db.add(product)
    await db.commit()
    await db.refresh(product)
    
    # Log inventory
    inv_log = InventoryLog(
        product_id=product.id,
        action="add",
        quantity_change=product.stock,
        previous_stock=0,
        new_stock=product.stock,
        notes="Initial stock",
        created_by=user.id
    )
    db.add(inv_log)
    await db.commit()
    
    return product_to_dict(product)

@api_router.put("/admin/products/{product_id}")
async def admin_update_product(product_id: str, product_data: ProductUpdate, user: User = Depends(get_admin_user), db: AsyncSession = Depends(get_db)):
    result = await db.execute(select(Product).where(Product.id == product_id))
    product = result.scalar_one_or_none()
    if not product:
        raise HTTPException(status_code=404, detail="Product not found")
    
    update_data = product_data.model_dump(exclude_unset=True)
    
    # Track stock changes
    if "stock" in update_data and update_data["stock"] != product.stock:
        inv_log = InventoryLog(
            product_id=product.id,
            action="adjust",
            quantity_change=update_data["stock"] - product.stock,
            previous_stock=product.stock,
            new_stock=update_data["stock"],
            notes="Manual adjustment",
            created_by=user.id
        )
        db.add(inv_log)
    
    for key, value in update_data.items():
        setattr(product, key, value)
    
    await db.commit()
    await db.refresh(product)
    return product_to_dict(product)

@api_router.delete("/admin/products/{product_id}")
async def admin_delete_product(product_id: str, user: User = Depends(get_admin_user), db: AsyncSession = Depends(get_db)):
    result = await db.execute(select(Product).where(Product.id == product_id))
    product = result.scalar_one_or_none()
    if not product:
        raise HTTPException(status_code=404, detail="Product not found")
    
    product.is_active = False
    await db.commit()
    return {"message": "Product deleted"}

# Admin - Services CRUD
@api_router.get("/admin/services")
async def admin_get_services(include_inactive: bool = False, user: User = Depends(get_admin_user), db: AsyncSession = Depends(get_db)):
    query = select(Service)
    if not include_inactive:
        query = query.where(Service.is_active == True)
    query = query.order_by(desc(Service.created_at))
    result = await db.execute(query)
    services = result.scalars().all()
    return [service_to_dict(s) for s in services]

@api_router.post("/admin/services")
async def admin_create_service(service_data: ServiceCreate, user: User = Depends(get_admin_user), db: AsyncSession = Depends(get_db)):
    service = Service(**service_data.model_dump())
    db.add(service)
    await db.commit()
    await db.refresh(service)
    return service_to_dict(service)

@api_router.put("/admin/services/{service_id}")
async def admin_update_service(service_id: str, service_data: ServiceUpdate, user: User = Depends(get_admin_user), db: AsyncSession = Depends(get_db)):
    result = await db.execute(select(Service).where(Service.id == service_id))
    service = result.scalar_one_or_none()
    if not service:
        raise HTTPException(status_code=404, detail="Service not found")
    
    update_data = service_data.model_dump(exclude_unset=True)
    for key, value in update_data.items():
        setattr(service, key, value)
    
    await db.commit()
    await db.refresh(service)
    return service_to_dict(service)

@api_router.delete("/admin/services/{service_id}")
async def admin_delete_service(service_id: str, user: User = Depends(get_admin_user), db: AsyncSession = Depends(get_db)):
    result = await db.execute(select(Service).where(Service.id == service_id))
    service = result.scalar_one_or_none()
    if not service:
        raise HTTPException(status_code=404, detail="Service not found")
    
    service.is_active = False
    await db.commit()
    return {"message": "Service deleted"}

# Admin - Orders Management
@api_router.get("/admin/orders")
async def admin_get_orders(
    status: Optional[str] = None,
    limit: int = 50,
    user: User = Depends(get_admin_user),
    db: AsyncSession = Depends(get_db)
):
    query = select(Order).options(selectinload(Order.items), selectinload(Order.status_history), selectinload(Order.user))
    if status:
        query = query.where(Order.status == OrderStatus(status))
    query = query.order_by(desc(Order.created_at)).limit(limit)
    result = await db.execute(query)
    orders = result.scalars().all()
    return [{
        **order_to_dict(o),
        "user_name": o.user.name if o.user else "Unknown",
        "user_email": o.user.email if o.user else "Unknown"
    } for o in orders]

@api_router.put("/admin/orders/{order_id}/status")
async def admin_update_order_status(order_id: str, status_data: OrderStatusUpdate, user: User = Depends(get_admin_user), db: AsyncSession = Depends(get_db)):
    result = await db.execute(
        select(Order).where(Order.id == order_id).options(selectinload(Order.items))
    )
    order = result.scalar_one_or_none()
    if not order:
        raise HTTPException(status_code=404, detail="Order not found")
    
    new_status = OrderStatus(status_data.status)
    order.status = new_status
    if status_data.tracking_number:
        order.tracking_number = status_data.tracking_number
    
    # Handle refunds - restore stock
    if new_status == OrderStatus.REFUNDED:
        for item in order.items:
            result = await db.execute(select(Product).where(Product.id == item.product_id))
            product = result.scalar_one_or_none()
            if product:
                previous_stock = product.stock
                product.stock += item.quantity
                inv_log = InventoryLog(
                    product_id=product.id,
                    action="refund",
                    quantity_change=item.quantity,
                    previous_stock=previous_stock,
                    new_stock=product.stock,
                    notes=f"Refund for order {order_id}",
                    created_by=user.id
                )
                db.add(inv_log)
    
    # Add status history
    status_history = OrderStatusHistory(
        order_id=order.id,
        status=new_status,
        notes=status_data.notes,
        created_by=user.id
    )
    db.add(status_history)
    
    await db.commit()
    return {"message": "Order status updated"}

# Admin - Inventory Management
@api_router.get("/admin/inventory")
async def admin_get_inventory(user: User = Depends(get_admin_user), db: AsyncSession = Depends(get_db)):
    result = await db.execute(
        select(Product)
        .where(Product.is_active == True)
        .order_by(Product.stock)
    )
    products = result.scalars().all()
    return [{
        **product_to_dict(p),
        "is_low_stock": p.stock <= p.low_stock_threshold
    } for p in products]

@api_router.post("/admin/inventory/{product_id}/adjust")
async def admin_adjust_inventory(product_id: str, adjustment: InventoryAdjust, user: User = Depends(get_admin_user), db: AsyncSession = Depends(get_db)):
    result = await db.execute(select(Product).where(Product.id == product_id))
    product = result.scalar_one_or_none()
    if not product:
        raise HTTPException(status_code=404, detail="Product not found")
    
    previous_stock = product.stock
    product.stock = max(0, product.stock + adjustment.quantity_change)
    
    inv_log = InventoryLog(
        product_id=product.id,
        action="adjust" if adjustment.quantity_change >= 0 else "remove",
        quantity_change=adjustment.quantity_change,
        previous_stock=previous_stock,
        new_stock=product.stock,
        notes=adjustment.notes,
        created_by=user.id
    )
    db.add(inv_log)
    await db.commit()
    
    return {"message": "Inventory adjusted", "new_stock": product.stock}

@api_router.get("/admin/inventory/{product_id}/logs")
async def admin_get_inventory_logs(product_id: str, user: User = Depends(get_admin_user), db: AsyncSession = Depends(get_db)):
    result = await db.execute(
        select(InventoryLog)
        .where(InventoryLog.product_id == product_id)
        .order_by(desc(InventoryLog.created_at))
        .limit(50)
    )
    logs = result.scalars().all()
    return [{
        "id": log.id,
        "action": log.action,
        "quantity_change": log.quantity_change,
        "previous_stock": log.previous_stock,
        "new_stock": log.new_stock,
        "notes": log.notes,
        "created_at": log.created_at.isoformat() if log.created_at else None
    } for log in logs]

# Admin - Bookings Management
@api_router.get("/admin/bookings")
async def admin_get_bookings(status: Optional[str] = None, user: User = Depends(get_admin_user), db: AsyncSession = Depends(get_db)):
    query = select(Booking).options(selectinload(Booking.service))
    if status:
        query = query.where(Booking.status == status)
    query = query.order_by(desc(Booking.created_at))
    result = await db.execute(query)
    bookings = result.scalars().all()
    return [booking_to_dict(b) for b in bookings]

@api_router.put("/admin/bookings/{booking_id}/status")
async def admin_update_booking_status(booking_id: str, status: str, user: User = Depends(get_admin_user), db: AsyncSession = Depends(get_db)):
    result = await db.execute(select(Booking).where(Booking.id == booking_id))
    booking = result.scalar_one_or_none()
    if not booking:
        raise HTTPException(status_code=404, detail="Booking not found")
    
    booking.status = status
    await db.commit()
    return {"message": "Booking status updated"}

# Admin - Users Management
@api_router.get("/admin/users")
async def admin_get_users(user: User = Depends(get_admin_user), db: AsyncSession = Depends(get_db)):
    result = await db.execute(select(User).order_by(desc(User.created_at)))
    users = result.scalars().all()
    return [user_to_dict(u) for u in users]

# Admin - Reports
@api_router.get("/admin/reports/sales")
async def admin_get_sales_report(
    period: str = "daily",  # daily, weekly, monthly
    start_date: Optional[str] = None,
    end_date: Optional[str] = None,
    user: User = Depends(get_admin_user),
    db: AsyncSession = Depends(get_db)
):
    now = datetime.now(timezone.utc)
    
    if start_date:
        start = datetime.fromisoformat(start_date.replace('Z', '+00:00'))
    else:
        if period == "daily":
            start = now - timedelta(days=30)
        elif period == "weekly":
            start = now - timedelta(weeks=12)
        else:
            start = now - timedelta(days=365)
    
    if end_date:
        end = datetime.fromisoformat(end_date.replace('Z', '+00:00'))
    else:
        end = now
    
    # Get orders in date range
    result = await db.execute(
        select(Order)
        .where(and_(Order.created_at >= start, Order.created_at <= end))
        .options(selectinload(Order.items))
        .order_by(Order.created_at)
    )
    orders = result.scalars().all()
    
    # Get bookings in date range
    bookings_result = await db.execute(
        select(Booking)
        .where(and_(Booking.created_at >= start, Booking.created_at <= end))
    )
    bookings = bookings_result.scalars().all()
    
    # Aggregate by period
    report_data = {}
    for order in orders:
        if period == "daily":
            key = order.created_at.strftime("%Y-%m-%d")
        elif period == "weekly":
            key = order.created_at.strftime("%Y-W%W")
        else:
            key = order.created_at.strftime("%Y-%m")
        
        if key not in report_data:
            report_data[key] = {
                "period": key,
                "orders": 0,
                "revenue": 0,
                "products_sold": 0,
                "order_statuses": {}
            }
        
        report_data[key]["orders"] += 1
        report_data[key]["revenue"] += order.total
        report_data[key]["products_sold"] += sum(item.quantity for item in order.items)
        
        status = order.status.value if order.status else "unknown"
        report_data[key]["order_statuses"][status] = report_data[key]["order_statuses"].get(status, 0) + 1
    
    # Add booking counts
    for booking in bookings:
        if period == "daily":
            key = booking.created_at.strftime("%Y-%m-%d")
        elif period == "weekly":
            key = booking.created_at.strftime("%Y-W%W")
        else:
            key = booking.created_at.strftime("%Y-%m")
        
        if key not in report_data:
            report_data[key] = {
                "period": key,
                "orders": 0,
                "revenue": 0,
                "products_sold": 0,
                "order_statuses": {}
            }
        
        report_data[key]["services_booked"] = report_data[key].get("services_booked", 0) + 1
    
    # Calculate totals
    total_orders = len(orders)
    total_revenue = sum(o.total for o in orders)
    total_products = sum(sum(item.quantity for item in o.items) for o in orders)
    total_bookings = len(bookings)
    
    return {
        "period": period,
        "start_date": start.isoformat(),
        "end_date": end.isoformat(),
        "summary": {
            "total_orders": total_orders,
            "total_revenue": total_revenue,
            "total_products_sold": total_products,
            "total_services_booked": total_bookings,
            "average_order_value": total_revenue / total_orders if total_orders > 0 else 0
        },
        "data": list(report_data.values())
    }

# Admin - Export Reports
@api_router.get("/admin/reports/export/csv")
async def admin_export_csv(
    report_type: str = "sales",  # sales, inventory, orders
    period: str = "monthly",
    user: User = Depends(get_admin_user),
    db: AsyncSession = Depends(get_db)
):
    output = io.StringIO()
    writer = csv.writer(output)
    
    now = datetime.now(timezone.utc)
    
    if report_type == "sales":
        if period == "daily":
            start = now - timedelta(days=30)
        elif period == "weekly":
            start = now - timedelta(weeks=12)
        else:
            start = now - timedelta(days=365)
        
        result = await db.execute(
            select(Order)
            .where(Order.created_at >= start)
            .options(selectinload(Order.items), selectinload(Order.user))
            .order_by(Order.created_at)
        )
        orders = result.scalars().all()
        
        writer.writerow(["Date", "Order ID", "Customer", "Items", "Subtotal", "Tax", "Shipping", "Total", "Status"])
        for order in orders:
            writer.writerow([
                order.created_at.strftime("%Y-%m-%d %H:%M"),
                order.id,
                order.user.name if order.user else "Guest",
                sum(item.quantity for item in order.items),
                f"${order.subtotal:.2f}",
                f"${order.tax:.2f}",
                f"${order.shipping:.2f}",
                f"${order.total:.2f}",
                order.status.value if order.status else "unknown"
            ])
    
    elif report_type == "inventory":
        result = await db.execute(select(Product).where(Product.is_active == True))
        products = result.scalars().all()
        
        writer.writerow(["Product ID", "Name", "Category", "Brand", "Price", "Stock", "Low Stock Threshold", "Status"])
        for product in products:
            writer.writerow([
                product.id,
                product.name,
                product.category,
                product.brand,
                f"${product.price:.2f}",
                product.stock,
                product.low_stock_threshold,
                "Low Stock" if product.stock <= product.low_stock_threshold else "In Stock"
            ])
    
    elif report_type == "orders":
        result = await db.execute(
            select(Order)
            .options(selectinload(Order.items), selectinload(Order.user))
            .order_by(desc(Order.created_at))
            .limit(500)
        )
        orders = result.scalars().all()
        
        writer.writerow(["Order ID", "Date", "Customer", "Email", "Items", "Total", "Status", "Tracking"])
        for order in orders:
            writer.writerow([
                order.id,
                order.created_at.strftime("%Y-%m-%d %H:%M"),
                order.user.name if order.user else "Guest",
                order.user.email if order.user else "",
                sum(item.quantity for item in order.items),
                f"${order.total:.2f}",
                order.status.value if order.status else "unknown",
                order.tracking_number or ""
            ])
    
    output.seek(0)
    return StreamingResponse(
        iter([output.getvalue()]),
        media_type="text/csv",
        headers={"Content-Disposition": f"attachment; filename={report_type}_report_{now.strftime('%Y%m%d')}.csv"}
    )

@api_router.get("/admin/reports/export/pdf")
async def admin_export_pdf(
    report_type: str = "sales",
    period: str = "monthly",
    user: User = Depends(get_admin_user),
    db: AsyncSession = Depends(get_db)
):
    buffer = io.BytesIO()
    doc = SimpleDocTemplate(buffer, pagesize=A4)
    styles = getSampleStyleSheet()
    elements = []
    
    now = datetime.now(timezone.utc)
    
    # Title
    title_style = ParagraphStyle(
        'CustomTitle',
        parent=styles['Heading1'],
        fontSize=24,
        spaceAfter=30
    )
    elements.append(Paragraph(f"TechZone {report_type.title()} Report", title_style))
    elements.append(Paragraph(f"Generated: {now.strftime('%Y-%m-%d %H:%M')}", styles['Normal']))
    elements.append(Spacer(1, 20))
    
    if report_type == "sales":
        if period == "daily":
            start = now - timedelta(days=30)
        elif period == "weekly":
            start = now - timedelta(weeks=12)
        else:
            start = now - timedelta(days=365)
        
        result = await db.execute(
            select(Order)
            .where(Order.created_at >= start)
            .options(selectinload(Order.items))
        )
        orders = result.scalars().all()
        
        # Summary
        total_orders = len(orders)
        total_revenue = sum(o.total for o in orders)
        total_products = sum(sum(item.quantity for item in o.items) for o in orders)
        
        elements.append(Paragraph("Summary", styles['Heading2']))
        summary_data = [
            ["Metric", "Value"],
            ["Total Orders", str(total_orders)],
            ["Total Revenue", f"${total_revenue:.2f}"],
            ["Products Sold", str(total_products)],
            ["Average Order Value", f"${total_revenue/total_orders:.2f}" if total_orders > 0 else "$0.00"]
        ]
        summary_table = Table(summary_data, colWidths=[3*inch, 2*inch])
        summary_table.setStyle(TableStyle([
            ('BACKGROUND', (0, 0), (-1, 0), colors.grey),
            ('TEXTCOLOR', (0, 0), (-1, 0), colors.whitesmoke),
            ('ALIGN', (0, 0), (-1, -1), 'CENTER'),
            ('FONTNAME', (0, 0), (-1, 0), 'Helvetica-Bold'),
            ('FONTSIZE', (0, 0), (-1, 0), 12),
            ('BOTTOMPADDING', (0, 0), (-1, 0), 12),
            ('BACKGROUND', (0, 1), (-1, -1), colors.beige),
            ('GRID', (0, 0), (-1, -1), 1, colors.black)
        ]))
        elements.append(summary_table)
        elements.append(Spacer(1, 20))
        
        # Orders table
        elements.append(Paragraph("Recent Orders", styles['Heading2']))
        orders_data = [["Date", "Order ID", "Items", "Total", "Status"]]
        for order in orders[:50]:
            orders_data.append([
                order.created_at.strftime("%Y-%m-%d"),
                order.id[:8] + "...",
                str(sum(item.quantity for item in order.items)),
                f"${order.total:.2f}",
                order.status.value if order.status else "unknown"
            ])
        
        orders_table = Table(orders_data, colWidths=[1.2*inch, 1.2*inch, 0.8*inch, 1*inch, 1*inch])
        orders_table.setStyle(TableStyle([
            ('BACKGROUND', (0, 0), (-1, 0), colors.grey),
            ('TEXTCOLOR', (0, 0), (-1, 0), colors.whitesmoke),
            ('ALIGN', (0, 0), (-1, -1), 'CENTER'),
            ('FONTNAME', (0, 0), (-1, 0), 'Helvetica-Bold'),
            ('FONTSIZE', (0, 0), (-1, -1), 9),
            ('BOTTOMPADDING', (0, 0), (-1, 0), 12),
            ('GRID', (0, 0), (-1, -1), 0.5, colors.black)
        ]))
        elements.append(orders_table)
    
    elif report_type == "inventory":
        result = await db.execute(select(Product).where(Product.is_active == True).order_by(Product.stock))
        products = result.scalars().all()
        
        elements.append(Paragraph("Inventory Status", styles['Heading2']))
        inv_data = [["Product", "Category", "Price", "Stock", "Status"]]
        for product in products:
            status = "LOW STOCK" if product.stock <= product.low_stock_threshold else "In Stock"
            inv_data.append([
                product.name[:30] + "..." if len(product.name) > 30 else product.name,
                product.category,
                f"${product.price:.2f}",
                str(product.stock),
                status
            ])
        
        inv_table = Table(inv_data, colWidths=[2*inch, 1*inch, 0.8*inch, 0.6*inch, 0.8*inch])
        inv_table.setStyle(TableStyle([
            ('BACKGROUND', (0, 0), (-1, 0), colors.grey),
            ('TEXTCOLOR', (0, 0), (-1, 0), colors.whitesmoke),
            ('ALIGN', (0, 0), (-1, -1), 'CENTER'),
            ('FONTNAME', (0, 0), (-1, 0), 'Helvetica-Bold'),
            ('FONTSIZE', (0, 0), (-1, -1), 8),
            ('BOTTOMPADDING', (0, 0), (-1, 0), 12),
            ('GRID', (0, 0), (-1, -1), 0.5, colors.black)
        ]))
        elements.append(inv_table)
    
    doc.build(elements)
    buffer.seek(0)
    
    return StreamingResponse(
        buffer,
        media_type="application/pdf",
        headers={"Content-Disposition": f"attachment; filename={report_type}_report_{now.strftime('%Y%m%d')}.pdf"}
    )

# ================== SEED DATA ==================

@api_router.post("/seed")
async def seed_data(db: AsyncSession = Depends(get_db)):
    # Check if data exists
    result = await db.execute(select(func.count(Product.id)))
    if result.scalar() > 0:
        return {"message": "Data already seeded"}
    
    # Create admin user
    admin = User(
        email="admin@techzone.com",
        name="Admin",
        password=hash_password("admin123"),
        role=UserRole.ADMIN
    )
    db.add(admin)
    
    # Create products
    products = [
        Product(name="MacBook Pro 16\"", description="Powerful laptop with M3 Pro chip, 18GB RAM, 512GB SSD.", price=2499.99, category="laptops", image_url="https://images.unsplash.com/photo-1517336714731-489689fd1ca8?w=800", stock=15, brand="Apple", specs={"processor": "M3 Pro", "ram": "18GB", "storage": "512GB SSD"}),
        Product(name="Dell XPS 15", description="Ultra-thin laptop with Intel Core i7, 16GB RAM, stunning OLED display.", price=1799.99, category="laptops", image_url="https://images.unsplash.com/photo-1593642632559-0c6d3fc62b89?w=800", stock=20, brand="Dell", specs={"processor": "Intel i7", "ram": "16GB", "storage": "512GB SSD"}),
        Product(name="iPhone 15 Pro Max", description="Latest iPhone with titanium design, A17 Pro chip, 48MP camera.", price=1199.99, category="phones", image_url="https://images.unsplash.com/photo-1695048133142-1a20484d2569?w=800", stock=30, brand="Apple", specs={"display": "6.7\" OLED", "camera": "48MP", "storage": "256GB"}),
        Product(name="Samsung Galaxy S24 Ultra", description="Premium Android phone with S Pen, 200MP camera, AI features.", price=1299.99, category="phones", image_url="https://images.unsplash.com/photo-1610945265064-0e34e5519bbf?w=800", stock=25, brand="Samsung", specs={"display": "6.8\" AMOLED", "camera": "200MP", "storage": "512GB"}),
        Product(name="Sony WH-1000XM5", description="Industry-leading noise cancellation, 30-hour battery.", price=349.99, category="accessories", image_url="https://images.unsplash.com/photo-1505740420928-5e560c06d30e?w=800", stock=40, brand="Sony", specs={"type": "Over-ear", "battery": "30 hours"}),
        Product(name="iPad Pro 12.9\"", description="Powerful tablet with M2 chip, Liquid Retina XDR display.", price=1099.99, category="tablets", image_url="https://images.unsplash.com/photo-1544244015-0df4b3ffc6b0?w=800", stock=18, brand="Apple", specs={"processor": "M2", "display": "12.9\" XDR"}),
        Product(name="Apple Watch Ultra 2", description="Rugged smartwatch with titanium case, GPS, 36-hour battery.", price=799.99, category="wearables", image_url="https://images.unsplash.com/photo-1434493789847-2f02dc6ca35d?w=800", stock=22, brand="Apple", specs={"display": "49mm", "battery": "36 hours"}),
        Product(name="Logitech MX Master 3S", description="Premium wireless mouse with 8K DPI sensor, silent clicks.", price=99.99, category="accessories", image_url="https://images.unsplash.com/photo-1527864550417-7fd91fc51a46?w=800", stock=50, brand="Logitech", specs={"sensor": "8K DPI", "battery": "70 days"}),
    ]
    for p in products:
        db.add(p)
    
    # Create services
    services = [
        Service(name="Screen Repair", description="Professional screen replacement for phones, tablets, and laptops.", price=149.99, duration="1-2 hours", image_url="https://images.unsplash.com/photo-1581092918056-0c4c3acd3789?w=800", category="repair"),
        Service(name="Battery Replacement", description="Restore your device's battery life with genuine replacement.", price=79.99, duration="30-60 mins", image_url="https://images.unsplash.com/photo-1609091839311-d5365f9ff1c5?w=800", category="repair"),
        Service(name="Data Recovery", description="Professional data recovery from damaged drives.", price=199.99, duration="2-5 days", image_url="https://images.unsplash.com/photo-1558494949-ef010cbdcc31?w=800", category="data"),
        Service(name="Virus Removal", description="Complete malware and virus removal with system optimization.", price=89.99, duration="1-3 hours", image_url="https://images.unsplash.com/photo-1526374965328-7f61d4dc18c5?w=800", category="software"),
        Service(name="Hardware Upgrade", description="Upgrade your RAM, SSD, or other components.", price=49.99, duration="1-2 hours", image_url="https://images.unsplash.com/photo-1591799265444-d66432b91588?w=800", category="upgrade"),
        Service(name="Device Setup", description="Complete setup service for new devices including data transfer.", price=59.99, duration="1-2 hours", image_url="https://images.unsplash.com/photo-1531297484001-80022131f5a1?w=800", category="setup"),
    ]
    for s in services:
        db.add(s)
    
    await db.commit()
    return {"message": "Data seeded successfully"}

# ================== ROOT ==================

@api_router.get("/")
async def root():
    return {"message": "TechZone API is running", "version": "2.0.0"}

# Include the router
app.include_router(api_router)

app.add_middleware(
    CORSMiddleware,
    allow_credentials=True,
    allow_origins=os.environ.get('CORS_ORIGINS', '*').split(','),
    allow_methods=["*"],
    allow_headers=["*"],
)

# Configure logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)

@app.on_event("startup")
async def startup_event():
    await init_db()
    logger.info("Database initialized")

@app.on_event("shutdown")
async def shutdown_event():
    pass
