import fs from 'fs';
import path from 'path';
import crypto from 'crypto';
import type { User, Category, Product, Coupon, Order, DashboardStats, Role } from '../src/types.js';

interface DatabaseSchema {
  schemaVersion?: number;
  users: (User & { passwordHash: string; salt: string })[];
  categories: Category[];
  products: Product[];
  coupons: Coupon[];
  orders: Order[];
}

const DATA_DIR = path.join(process.cwd(), 'data');
const DB_FILE = path.join(DATA_DIR, 'zanashop_db.json');

// Helper to hash passwords securely
export function hashPassword(password: string, salt?: string): { hash: string; salt: string } {
  const generatedSalt = salt || crypto.randomBytes(16).toString('hex');
  const hash = crypto.pbkdf2Sync(password, generatedSalt, 1000, 64, 'sha512').toString('hex');
  return { hash, salt: generatedSalt };
}

export function verifyPassword(password: string, hash: string, salt: string): boolean {
  const check = crypto.pbkdf2Sync(password, salt, 1000, 64, 'sha512').toString('hex');
  return check === hash;
}

// Initial seed data
function getInitialSeedData(): DatabaseSchema {
  const adminAuth = hashPassword('admin123456');
  const userAuth = hashPassword('user123456');

  const now = new Date().toISOString();

  const categories: Category[] = [
    {
      id: 'cat_gaming_service',
      name: 'سرویس WireGuard',
      slug: 'wireguard',
      icon: 'Zap',
      description: 'سرویس‌های اختصاصی WireGuard برای گیم و اینترنت پایدار',
      isActive: true,
      sortOrder: 1,
      createdAt: now,
    },
  ];

  const products: Product[] = [
    {
      id: 'prod_wireguard_36gb_1m',
      title: 'WireGuard — ۳۶ گیگابایت / ۱ ماهه',
      slug: 'wireguard-36gb-1month',
      categoryId: 'cat_gaming_service',
      price: 399000,
      description: 'سرویس WireGuard اختصاصی برای یک کاربر، مناسب گیمینگ و اتصال پایدار. حجم ۳۶ گیگابایت با اعتبار ۱ ماهه.',
      features: [
        'یک کاربر',
        '۳۶ گیگابایت ترافیک',
        'اعتبار ۱ ماهه',
        'پروتکل WireGuard',
        'تحویل کانفیگ پس از تأیید سفارش',
        'پشتیبانی تلگرام'
      ],
      tags: ['WireGuard', 'کاهش پینگ', '۳۶ گیگ', '۱ ماهه'],
      image: '/src/assets/images/wireguard_36gb_card.jpg',
      badge: 'شروع از ۳۹۹ هزار تومان',
      inStock: true,
      stockCount: 999,
      isFeatured: true,
      isBestSeller: true,
      platform: 'gaming_service',
      deliveryType: 'manual_config',
      deliveryNote: 'پس از ثبت و تأیید سفارش، کانفیگ WireGuard برای یک کاربر از طریق ایمیل یا پشتیبانی تلگرام تحویل می‌شود.',
      createdAt: now,
    },
    {
      id: 'prod_wireguard_127gb_2m',
      title: 'WireGuard — ۱۲۷ گیگابایت / ۲ ماهه',
      slug: 'wireguard-127gb-2month',
      categoryId: 'cat_gaming_service',
      price: 798000,
      description: 'سرویس WireGuard اختصاصی برای یک کاربر، مناسب استفاده طولانی‌تر. حجم ۱۲۷ گیگابایت با اعتبار ۲ ماهه.',
      features: [
        'یک کاربر',
        '۱۲۷ گیگابایت ترافیک',
        'اعتبار ۲ ماهه',
        'پروتکل WireGuard',
        'تحویل کانفیگ پس از تأیید سفارش',
        'پشتیبانی تلگرام'
      ],
      tags: ['WireGuard', 'کاهش پینگ', '۱۲۷ گیگ', '۲ ماهه'],
      image: '/src/assets/images/wireguard_127gb_card.jpg',
      badge: 'به‌صرفه',
      inStock: true,
      stockCount: 999,
      isFeatured: true,
      isBestSeller: false,
      platform: 'gaming_service',
      deliveryType: 'manual_config',
      deliveryNote: 'پس از ثبت و تأیید سفارش، کانفیگ WireGuard برای یک کاربر از طریق ایمیل یا پشتیبانی تلگرام تحویل می‌شود.',
      createdAt: now,
    },
  ];

  const coupons: Coupon[] = [
    {
      id: 'coup_zana2025',
      code: 'ZANA',
      discountType: 'percent',
      discountValue: 15,
      minPurchase: 200000,
      maxDiscount: 150000,
      maxUses: 500,
      usedCount: 38,
      isActive: true,
      startDate: '2025-01-01',
      endDate: '2027-12-31',
      createdAt: now,
    },
    {
      id: 'coup_gamer',
      code: 'GAMER50',
      discountType: 'fixed',
      discountValue: 50000,
      minPurchase: 300000,
      maxUses: 200,
      usedCount: 14,
      isActive: true,
      startDate: '2025-01-01',
      endDate: '2027-12-31',
      createdAt: now,
    }
  ];

  const orders: Order[] = [];

  const users: (User & { passwordHash: string; salt: string })[] = [
    {
      id: 'usr_admin',
      name: 'مدیر کل ZaccShop',
      email: 'zanagameyoutubbe@gmail.com',
      mobile: '09120000000',
      role: 'admin',
      isActive: true,
      createdAt: now,
      passwordHash: adminAuth.hash,
      salt: adminAuth.salt,
    },
    {
      id: 'usr_admin2',
      name: 'ادمین سیستم',
      email: 'admin@zaccshop.ir',
      mobile: '09121112233',
      role: 'admin',
      isActive: true,
      createdAt: now,
      passwordHash: adminAuth.hash,
      salt: adminAuth.salt,
    },
    {
      id: 'usr_customer',
      name: 'کاربر تستی زاناشاپ',
      email: 'user@zaccshop.ir',
      mobile: '09351234567',
      role: 'user',
      isActive: true,
      createdAt: now,
      passwordHash: userAuth.hash,
      salt: userAuth.salt,
    }
  ];

  return {
    schemaVersion: 2,
    users,
    categories,
    products,
    coupons,
    orders,
  };
}

class Database {
  private data: DatabaseSchema;

  constructor() {
    this.ensureDataDir();
    this.data = this.loadData();
  }

  private ensureDataDir() {
    if (!fs.existsSync(DATA_DIR)) {
      fs.mkdirSync(DATA_DIR, { recursive: true });
    }
  }

  private loadData(): DatabaseSchema {
    try {
      if (fs.existsSync(DB_FILE)) {
        const raw = fs.readFileSync(DB_FILE, 'utf-8');
        const existing = JSON.parse(raw) as DatabaseSchema;

        // Development migration: ZaccShop is currently focused only on WireGuard.
        // Preserve users/coupons, but reset the catalog and demo orders once.
        if ((existing.schemaVersion || 0) < 2) {
          const seed = getInitialSeedData();
          const migrated: DatabaseSchema = {
            schemaVersion: 2,
            users: existing.users?.length ? existing.users : seed.users,
            categories: seed.categories,
            products: seed.products,
            coupons: existing.coupons || seed.coupons,
            orders: [],
          };
          this.saveDataDirect(migrated);
          return migrated;
        }

        return existing;
      }
    } catch (err) {
      console.error('Error loading database file, re-initializing seed data:', err);
    }
    const seed = getInitialSeedData();
    this.saveDataDirect(seed);
    return seed;
  }

  private saveDataDirect(data: DatabaseSchema) {
    this.ensureDataDir();
    const tempFile = `${DB_FILE}.tmp`;
    fs.writeFileSync(tempFile, JSON.stringify(data, null, 2), 'utf-8');
    fs.renameSync(tempFile, DB_FILE);
  }

  private persist() {
    this.saveDataDirect(this.data);
  }

  // --- Users ---
  getUsers(): User[] {
    return this.data.users.map(({ passwordHash, salt, ...safeUser }) => safeUser);
  }

  getUserById(id: string): User | undefined {
    const user = this.data.users.find(u => u.id === id);
    if (!user) return undefined;
    const { passwordHash, salt, ...safeUser } = user;
    return safeUser;
  }

  getUserByEmail(email: string) {
    return this.data.users.find(u => u.email.toLowerCase() === email.toLowerCase());
  }

  createUser(name: string, email: string, mobile: string, passwordPlain: string, role: Role = 'user'): User {
    const existing = this.getUserByEmail(email);
    if (existing) {
      throw new Error('کاربری با این ایمیل قبلاً ثبت نام کرده است');
    }
    const { hash, salt } = hashPassword(passwordPlain);
    const newUser: User & { passwordHash: string; salt: string } = {
      id: `usr_${Date.now()}_${Math.random().toString(36).substring(2, 6)}`,
      name,
      email: email.toLowerCase().trim(),
      mobile: mobile.trim(),
      role,
      isActive: true,
      createdAt: new Date().toISOString(),
      passwordHash: hash,
      salt,
    };
    this.data.users.push(newUser);
    this.persist();
    const { passwordHash, salt: _, ...safeUser } = newUser;
    return safeUser;
  }

  updateUser(id: string, updates: Partial<User>): User {
    const idx = this.data.users.findIndex(u => u.id === id);
    if (idx === -1) throw new Error('کاربر یافت نشد');
    const current = this.data.users[idx];
    this.data.users[idx] = {
      ...current,
      ...updates,
      id: current.id, // prevent id change
    };
    this.persist();
    const { passwordHash, salt, ...safeUser } = this.data.users[idx];
    return safeUser;
  }

  // --- Categories ---
  getCategories(onlyActive = false): Category[] {
    let cats = this.data.categories;
    if (onlyActive) {
      cats = cats.filter(c => c.isActive);
    }
    // calculate product count dynamically
    return cats
      .map(cat => ({
        ...cat,
        productCount: this.data.products.filter(p => p.categoryId === cat.id && (onlyActive ? p.inStock : true)).length,
      }))
      .sort((a, b) => a.sortOrder - b.sortOrder);
  }

  getCategoryById(id: string): Category | undefined {
    return this.data.categories.find(c => c.id === id);
  }

  createCategory(payload: Omit<Category, 'id' | 'createdAt'>): Category {
    const newCategory: Category = {
      id: `cat_${Date.now()}_${Math.random().toString(36).substring(2, 5)}`,
      name: payload.name.trim(),
      slug: payload.slug.trim().toLowerCase().replace(/\s+/g, '-'),
      icon: payload.icon || 'Folder',
      description: payload.description || '',
      isActive: payload.isActive ?? true,
      sortOrder: Number(payload.sortOrder) || (this.data.categories.length + 1),
      createdAt: new Date().toISOString(),
    };
    this.data.categories.push(newCategory);
    this.persist();
    return newCategory;
  }

  updateCategory(id: string, updates: Partial<Category>): Category {
    const idx = this.data.categories.findIndex(c => c.id === id);
    if (idx === -1) throw new Error('دسته‌بندی یافت نشد');
    this.data.categories[idx] = {
      ...this.data.categories[idx],
      ...updates,
      id,
    };
    this.persist();
    return this.data.categories[idx];
  }

  deleteCategory(id: string): boolean {
    const productUsing = this.data.products.some(p => p.categoryId === id);
    if (productUsing) {
      throw new Error('نمی‌توان دسته‌بندی دارای محصول را حذف کرد. ابتدا محصولات آن را تغییر دهید.');
    }
    const initialLen = this.data.categories.length;
    this.data.categories = this.data.categories.filter(c => c.id !== id);
    if (this.data.categories.length !== initialLen) {
      this.persist();
      return true;
    }
    return false;
  }

  // --- Products ---
  getProducts(filters?: {
    categoryId?: string;
    search?: string;
    onlyActive?: boolean;
    sort?: string;
    isFeatured?: boolean;
    minPrice?: number;
    maxPrice?: number;
  }): Product[] {
    let result = [...this.data.products];

    if (filters?.onlyActive) {
      // only in-stock or active
      result = result.filter(p => p.inStock);
    }

    if (filters?.categoryId) {
      result = result.filter(p => p.categoryId === filters.categoryId);
    }

    if (filters?.isFeatured) {
      result = result.filter(p => p.isFeatured);
    }

    if (filters?.minPrice !== undefined && filters.minPrice > 0) {
      result = result.filter(p => p.price >= (filters.minPrice || 0));
    }

    if (filters?.maxPrice !== undefined && filters.maxPrice > 0) {
      result = result.filter(p => p.price <= (filters.maxPrice || Infinity));
    }

    if (filters?.search) {
      const q = filters.search.toLowerCase().trim();
      result = result.filter(p =>
        p.title.toLowerCase().includes(q) ||
        p.description.toLowerCase().includes(q) ||
        p.tags.some(t => t.toLowerCase().includes(q))
      );
    }

    // Attach category name
    result = result.map(p => {
      const cat = this.data.categories.find(c => c.id === p.categoryId);
      return {
        ...p,
        categoryName: cat?.name || 'سایر',
      };
    });

    // Sorting
    switch (filters?.sort) {
      case 'price_asc':
        result.sort((a, b) => a.price - b.price);
        break;
      case 'price_desc':
        result.sort((a, b) => b.price - a.price);
        break;
      case 'popular':
        result.sort((a, b) => (b.isBestSeller ? 1 : 0) - (a.isBestSeller ? 1 : 0));
        break;
      case 'discount':
        result.sort((a, b) => (b.discountPercent || 0) - (a.discountPercent || 0));
        break;
      case 'newest':
      default:
        result.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime());
        break;
    }

    return result;
  }

  getProductById(id: string): Product | undefined {
    const prod = this.data.products.find(p => p.id === id || p.slug === id);
    if (!prod) return undefined;
    const cat = this.data.categories.find(c => c.id === prod.categoryId);
    return {
      ...prod,
      categoryName: cat?.name || 'سایر',
    };
  }

  createProduct(payload: Omit<Product, 'id' | 'createdAt'>): Product {
    const cat = this.data.categories.find(c => c.id === payload.categoryId);
    if (!cat) throw new Error('دسته‌بندی نامعتبر است');

    const price = Number(payload.price) || 0;
    const originalPrice = payload.originalPrice ? Number(payload.originalPrice) : undefined;
    let discountPercent = payload.discountPercent;
    if (!discountPercent && originalPrice && originalPrice > price) {
      discountPercent = Math.round(((originalPrice - price) / originalPrice) * 100);
    }

    const newProd: Product = {
      id: `prod_${Date.now()}_${Math.random().toString(36).substring(2, 5)}`,
      title: payload.title.trim(),
      slug: payload.slug ? payload.slug.trim().toLowerCase().replace(/\s+/g, '-') : `prod-${Date.now()}`,
      categoryId: payload.categoryId,
      categoryName: cat.name,
      price,
      originalPrice,
      discountPercent,
      description: payload.description || '',
      features: Array.isArray(payload.features) ? payload.features : [],
      tags: Array.isArray(payload.tags) ? payload.tags : [],
      image: payload.image || 'https://images.unsplash.com/photo-1618005182384-a83a8bd57fbe?auto=format&fit=crop&w=800&q=80',
      badge: payload.badge || '',
      inStock: payload.inStock ?? true,
      stockCount: Number(payload.stockCount) ?? 10,
      isFeatured: payload.isFeatured ?? false,
      isBestSeller: payload.isBestSeller ?? false,
      platform: payload.platform,
      regions: Array.isArray(payload.regions) ? payload.regions : [],
      deliveryType: payload.deliveryType || 'instant_code',
      deliveryNote: payload.deliveryNote || '',
      createdAt: new Date().toISOString(),
    };

    this.data.products.push(newProd);
    this.persist();
    return newProd;
  }

  updateProduct(id: string, updates: Partial<Product>): Product {
    const idx = this.data.products.findIndex(p => p.id === id);
    if (idx === -1) throw new Error('محصول مورد نظر پیدا نشد');

    const current = this.data.products[idx];
    const price = updates.price !== undefined ? Number(updates.price) : current.price;
    const originalPrice = updates.originalPrice !== undefined ? (updates.originalPrice ? Number(updates.originalPrice) : undefined) : current.originalPrice;
    
    let discountPercent = updates.discountPercent;
    if (discountPercent === undefined && originalPrice && originalPrice > price) {
      discountPercent = Math.round(((originalPrice - price) / originalPrice) * 100);
    }

    const cat = updates.categoryId ? this.data.categories.find(c => c.id === updates.categoryId) : this.data.categories.find(c => c.id === current.categoryId);

    this.data.products[idx] = {
      ...current,
      ...updates,
      price,
      originalPrice,
      discountPercent,
      categoryId: updates.categoryId || current.categoryId,
      categoryName: cat?.name || current.categoryName,
      id,
      updatedAt: new Date().toISOString(),
    };

    this.persist();
    return this.data.products[idx];
  }

  deleteProduct(id: string): boolean {
    const initial = this.data.products.length;
    this.data.products = this.data.products.filter(p => p.id !== id);
    if (this.data.products.length !== initial) {
      this.persist();
      return true;
    }
    return false;
  }

  // --- Coupons ---
  getCoupons(): Coupon[] {
    return [...this.data.coupons];
  }

  getCouponByCode(code: string): Coupon | undefined {
    return this.data.coupons.find(c => c.code.toUpperCase() === code.trim().toUpperCase());
  }

  validateCoupon(code: string, subtotal: number): { valid: boolean; discount: number; message: string; coupon?: Coupon } {
    const coupon = this.getCouponByCode(code);
    if (!coupon || !coupon.isActive) {
      return { valid: false, discount: 0, message: 'کد تخفیف نامعتبر یا منقضی شده است' };
    }

    if (coupon.maxUses > 0 && coupon.usedCount >= coupon.maxUses) {
      return { valid: false, discount: 0, message: 'ظرفیت استفاده از این کد تخفیف به اتمام رسیده است' };
    }

    if (subtotal < coupon.minPurchase) {
      return {
        valid: false,
        discount: 0,
        message: `حداقل مبلغ سفارش برای استفاده از این کد تخفیف ${coupon.minPurchase.toLocaleString('fa-IR')} تومان است`,
      };
    }

    let discount = 0;
    if (coupon.discountType === 'percent') {
      discount = Math.round((subtotal * coupon.discountValue) / 100);
      if (coupon.maxDiscount && discount > coupon.maxDiscount) {
        discount = coupon.maxDiscount;
      }
    } else {
      discount = coupon.discountValue;
    }

    if (discount > subtotal) discount = subtotal;

    return {
      valid: true,
      discount,
      message: `کد تخفیف با موفقیت اعمال شد (${discount.toLocaleString('fa-IR')} تومان تخفیف)`,
      coupon,
    };
  }

  createCoupon(payload: Omit<Coupon, 'id' | 'createdAt' | 'usedCount'>): Coupon {
    const existing = this.getCouponByCode(payload.code);
    if (existing) throw new Error('کد تخفیف با این نام از قبل وجود دارد');

    const newCoupon: Coupon = {
      id: `coup_${Date.now()}_${Math.random().toString(36).substring(2, 5)}`,
      code: payload.code.trim().toUpperCase(),
      discountType: payload.discountType || 'percent',
      discountValue: Number(payload.discountValue) || 0,
      minPurchase: Number(payload.minPurchase) || 0,
      maxDiscount: payload.maxDiscount ? Number(payload.maxDiscount) : undefined,
      maxUses: Number(payload.maxUses) || 100,
      usedCount: 0,
      isActive: payload.isActive ?? true,
      startDate: payload.startDate,
      endDate: payload.endDate,
      createdAt: new Date().toISOString(),
    };

    this.data.coupons.push(newCoupon);
    this.persist();
    return newCoupon;
  }

  updateCoupon(id: string, updates: Partial<Coupon>): Coupon {
    const idx = this.data.coupons.findIndex(c => c.id === id);
    if (idx === -1) throw new Error('کد تخفیف پیدا نشد');
    this.data.coupons[idx] = {
      ...this.data.coupons[idx],
      ...updates,
      code: updates.code ? updates.code.toUpperCase().trim() : this.data.coupons[idx].code,
      id,
    };
    this.persist();
    return this.data.coupons[idx];
  }

  deleteCoupon(id: string): boolean {
    const initial = this.data.coupons.length;
    this.data.coupons = this.data.coupons.filter(c => c.id !== id);
    if (this.data.coupons.length !== initial) {
      this.persist();
      return true;
    }
    return false;
  }

  // --- Orders ---
  getOrders(filters?: { userId?: string; status?: string }): Order[] {
    let result = [...this.data.orders];
    if (filters?.userId) {
      result = result.filter(o => o.userId === filters.userId);
    }
    if (filters?.status) {
      result = result.filter(o => o.orderStatus === filters.status);
    }
    return result.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime());
  }

  getOrderById(idOrNumber: string): Order | undefined {
    return this.data.orders.find(o => o.id === idOrNumber || o.orderNumber.toUpperCase() === idOrNumber.toUpperCase());
  }

  createOrder(payload: {
    userId?: string;
    guestInfo: { name: string; mobile: string; email: string; notes?: string };
    items: { productId: string; quantity: number; region?: string }[];
    couponCode?: string;
    paymentMethod: string;
  }): Order {
    if (!payload.items || payload.items.length === 0) {
      throw new Error('سبد خرید نمی‌تواند خالی باشد');
    }

    // Recalculate price strictly from DB to prevent client-side tampering
    let subtotal = 0;
    const verifiedItems = payload.items.map(item => {
      const prod = this.data.products.find(p => p.id === item.productId);
      if (!prod) throw new Error(`محصول با شناسه ${item.productId} معتبر نیست`);
      if (!prod.inStock) throw new Error(`محصول "${prod.title}" در حال حاضر موجود نیست`);
      if (prod.regions?.length) {
        if (!item.region || !prod.regions.includes(item.region)) {
          throw new Error(`لطفاً ریجن معتبر محصول "${prod.title}" را انتخاب کنید`);
        }
      }

      const price = prod.price;
      const quantity = Math.max(1, Number(item.quantity) || 1);
      subtotal += price * quantity;

      return {
        productId: prod.id,
        title: prod.title,
        region: item.region,
        price,
        originalPrice: prod.originalPrice,
        quantity,
        image: prod.image,
      };
    });

    let discountAmount = 0;
    if (payload.couponCode) {
      const couponCheck = this.validateCoupon(payload.couponCode, subtotal);
      if (couponCheck.valid && couponCheck.coupon) {
        discountAmount = couponCheck.discount;
        // increment coupon usage
        couponCheck.coupon.usedCount += 1;
      }
    }

    const finalTotal = Math.max(0, subtotal - discountAmount);
    const orderNumber = `ZNA-${Math.floor(100000 + Math.random() * 900000)}`;

    // Generate sample instant delivery keys if instant
    const generatedKeys: string[] = [];
    verifiedItems.forEach(item => {
      const prod = this.data.products.find(p => p.id === item.productId);
      if (prod?.deliveryType === 'instant_code') {
        for (let i = 0; i < item.quantity; i++) {
          generatedKeys.push(`KEY-${prod.slug.substring(0, 5).toUpperCase()}-${Math.random().toString(36).substring(2, 8).toUpperCase()}-${Math.floor(1000 + Math.random() * 9000)}`);
        }
      }
    });

    const newOrder: Order = {
      id: `ord_${Date.now()}_${Math.random().toString(36).substring(2, 5)}`,
      orderNumber,
      userId: payload.userId,
      guestInfo: payload.guestInfo,
      items: verifiedItems,
      subtotal,
      discountAmount,
      couponCode: payload.couponCode?.toUpperCase(),
      finalTotal,
      paymentMethod: payload.paymentMethod || 'online_gateway',
      paymentStatus: 'pending',
      orderStatus: 'pending_payment',
      licenseKeys: generatedKeys.length > 0 ? generatedKeys : undefined,
      deliveryInstructions: 'سفارش ثبت شد و پس از تأیید پرداخت، فرآیند تحویل انجام می‌شود.',
      createdAt: new Date().toISOString(),
      updatedAt: new Date().toISOString(),
    };

    this.data.orders.unshift(newOrder);
    this.persist();
    return newOrder;
  }

  updateOrderStatus(id: string, payload: {
    orderStatus?: Order['orderStatus'];
    paymentStatus?: Order['paymentStatus'];
    licenseKeys?: string[];
    deliveryInstructions?: string;
  }): Order {
    const idx = this.data.orders.findIndex(o => o.id === id || o.orderNumber === id);
    if (idx === -1) throw new Error('سفارش پیدا نشد');

    this.data.orders[idx] = {
      ...this.data.orders[idx],
      ...payload,
      updatedAt: new Date().toISOString(),
    };
    this.persist();
    return this.data.orders[idx];
  }

  // --- Stats for Admin Dashboard ---
  getDashboardStats(): DashboardStats {
    const totalOrders = this.data.orders.length;
    const completedOrders = this.data.orders.filter(o => o.orderStatus === 'completed').length;
    const pendingOrders = this.data.orders.filter(o => o.orderStatus === 'processing' || o.orderStatus === 'pending_payment').length;
    const totalSales = this.data.orders
      .filter(o => o.paymentStatus === 'paid')
      .reduce((sum, o) => sum + o.finalTotal, 0);

    const totalUsers = this.data.users.length;
    const totalProducts = this.data.products.length;

    // Top selling products calculation
    const salesMap: Record<string, { title: string; count: number; revenue: number }> = {};
    this.data.orders.forEach(ord => {
      if (ord.paymentStatus === 'paid') {
        ord.items.forEach(item => {
          if (!salesMap[item.productId]) {
            salesMap[item.productId] = { title: item.title, count: 0, revenue: 0 };
          }
          salesMap[item.productId].count += item.quantity;
          salesMap[item.productId].revenue += item.price * item.quantity;
        });
      }
    });

    const topProducts = Object.entries(salesMap)
      .map(([productId, info]) => ({
        productId,
        title: info.title,
        salesCount: info.count,
        revenue: info.revenue,
      }))
      .sort((a, b) => b.salesCount - a.salesCount)
      .slice(0, 5);

    return {
      totalSales,
      totalOrders,
      pendingOrders,
      completedOrders,
      totalUsers,
      totalProducts,
      recentOrders: this.data.orders.slice(0, 6),
      topProducts,
    };
  }
}

export const db = new Database();
