// Database adapter to gradually transition from localStorage to Firebase
import { 
  customerService, 
  orderService, 
  inventoryService,
  tailoringItemService,
  employeeService,
  incomeTransactionService,
  expenseTransactionService,
  customerMeasurementService,
  shopService,
  appearanceSettingsService,
  notificationSettingsService,
  dbUtils
} from './service';
import { 
  getMockCustomers,
  getMockOrders,
  getMockInventory,
  getMockTailoringItems,
  getMockEmployees,
  getMockIncome,
  getOtherExpenses,
  getMockMeasurements,
  getShopProfile,
  getAppearanceSettings,
  getNotificationSettings,
} from '../data';
import type {
  Customer,
  Order,
  InventoryItem,
  TailoringItem,
  Employee,
  Transaction,
  Expense,
  CustomerMeasurement,
  ShopProfile,
  AppearanceSettings,
  NotificationSettings,
} from '../data';
import { Timestamp } from 'firebase/firestore';

// Configuration to control data source
const USE_FIREBASE = process.env.NEXT_PUBLIC_USE_FIREBASE === 'true';
const SHOP_ID = 'default-shop'; // This should come from user context in real implementation

// Helper to convert Firebase data to localStorage format
function convertFirebaseToLocal<T>(firebaseData: any[]): T[] {
  return firebaseData.map(item => ({
    ...item,
    date: item.orderDate ? dbUtils.timestampToDate(item.orderDate).toISOString().split('T')[0] : undefined,
    transactionDate: item.transactionDate ? dbUtils.timestampToDate(item.transactionDate).toISOString().split('T')[0] : undefined,
    deliveryDate: item.deliveryDate ? dbUtils.timestampToDate(item.deliveryDate).toISOString().split('T')[0] : undefined,
    artisanAssignedDate: item.artisanAssignedDate ? dbUtils.timestampToDate(item.artisanAssignedDate).toISOString().split('T')[0] : undefined,
    artisanCompletedDate: item.artisanCompletedDate ? dbUtils.timestampToDate(item.artisanCompletedDate).toISOString().split('T')[0] : undefined,
    cuttingCompletedDate: item.cuttingCompletedDate ? dbUtils.timestampToDate(item.cuttingCompletedDate).toISOString().split('T')[0] : undefined,
  }));
}

// Adapter class for gradual migration
export class DatabaseAdapter {
  // Customers
  static async getCustomers(): Promise<Customer[]> {
    if (USE_FIREBASE) {
      const result = await customerService.getMany([], {}, SHOP_ID);
      if (result.success && result.data) {
        return convertFirebaseToLocal(result.data.data);
      }
    }
    return getMockCustomers();
  }

  static async addCustomer(customer: Omit<Customer, 'id'>): Promise<Customer> {
    if (USE_FIREBASE) {
      const result = await customerService.create({
        ...customer,
        shopId: SHOP_ID,
        totalOrders: 0,
        totalSpent: 0,
      });
      if (result.success && result.data) {
        return convertFirebaseToLocal([result.data])[0];
      }
    }
    
    // Fallback to localStorage
    const customers = getMockCustomers();
    const newCustomer = { ...customer, id: `CUST-${Date.now()}` };
    customers.push(newCustomer);
    localStorage.setItem('mockCustomers', JSON.stringify(customers));
    return newCustomer;
  }

  // Orders
  static async getOrders(): Promise<Order[]> {
    if (USE_FIREBASE) {
      const result = await orderService.getMany([], { orderBy: 'orderDate', orderDirection: 'desc' }, SHOP_ID);
      if (result.success && result.data) {
        return convertFirebaseToLocal(result.data.data);
      }
    }
    return getMockOrders();
  }

  static async addOrder(order: Omit<Order, 'id'>): Promise<Order> {
    if (USE_FIREBASE) {
      const result = await orderService.create({
        ...order,
        shopId: SHOP_ID,
        customerName: order.customer,
        customerPhone: order.phone,
        orderDate: Timestamp.fromDate(new Date(order.date)),
        deliveryDate: order.deliveryDate ? Timestamp.fromDate(new Date(order.deliveryDate)) : undefined,
        artisanAssignedDate: order.artisanAssignedDate ? Timestamp.fromDate(new Date(order.artisanAssignedDate)) : undefined,
        artisanCompletedDate: order.artisanCompletedDate ? Timestamp.fromDate(new Date(order.artisanCompletedDate)) : undefined,
        cuttingCompletedDate: order.cuttingCompletedDate ? Timestamp.fromDate(new Date(order.cuttingCompletedDate)) : undefined,
        artisanName: order.artisan,
        cuttingMasterName: order.cuttingMaster,
        priority: 'medium',
      });
      if (result.success && result.data) {
        return convertFirebaseToLocal([result.data])[0];
      }
    }
    
    // Fallback to localStorage
    const orders = getMockOrders();
    const newOrder = { ...order, id: `ORD-${Date.now()}` };
    orders.push(newOrder);
    localStorage.setItem('mockOrders', JSON.stringify(orders));
    return newOrder;
  }

  // Inventory
  static async getInventory(): Promise<InventoryItem[]> {
    if (USE_FIREBASE) {
      const result = await inventoryService.getMany([], {}, SHOP_ID);
      if (result.success && result.data) {
        return convertFirebaseToLocal(result.data.data);
      }
    }
    return getMockInventory();
  }

  static async addInventoryItem(item: Omit<InventoryItem, 'id'>): Promise<InventoryItem> {
    if (USE_FIREBASE) {
      const result = await inventoryService.create({
        ...item,
        shopId: SHOP_ID,
      });
      if (result.success && result.data) {
        return convertFirebaseToLocal([result.data])[0];
      }
    }
    
    // Fallback to localStorage
    const inventory = getMockInventory();
    const newItem = { ...item, id: `INV-${Date.now()}` };
    inventory.push(newItem);
    localStorage.setItem('mockInventory', JSON.stringify(inventory));
    return newItem;
  }

  // Tailoring Items
  static async getTailoringItems(): Promise<TailoringItem[]> {
    if (USE_FIREBASE) {
      const result = await tailoringItemService.getMany([], {}, SHOP_ID);
      if (result.success && result.data) {
        return convertFirebaseToLocal(result.data.data);
      }
    }
    return getMockTailoringItems();
  }

  // Employees
  static async getEmployees(): Promise<Employee[]> {
    if (USE_FIREBASE) {
      const result = await employeeService.getMany([], {}, SHOP_ID);
      if (result.success && result.data) {
        return convertFirebaseToLocal(result.data.data);
      }
    }
    return getMockEmployees();
  }

  // Income Transactions
  static async getIncomeTransactions(): Promise<Transaction[]> {
    if (USE_FIREBASE) {
      const result = await incomeTransactionService.getMany([], { orderBy: 'transactionDate', orderDirection: 'desc' }, SHOP_ID);
      if (result.success && result.data) {
        return convertFirebaseToLocal(result.data.data);
      }
    }
    return getMockIncome();
  }

  // Expense Transactions
  static async getExpenseTransactions(): Promise<Expense[]> {
    if (USE_FIREBASE) {
      const result = await expenseTransactionService.getMany([], { orderBy: 'transactionDate', orderDirection: 'desc' }, SHOP_ID);
      if (result.success && result.data) {
        return convertFirebaseToLocal(result.data.data);
      }
    }
    return getOtherExpenses();
  }

  // Customer Measurements
  static async getCustomerMeasurements(customerId?: string): Promise<CustomerMeasurement[]> {
    if (USE_FIREBASE) {
      const filters = customerId ? [{ field: 'customerId', operator: '==', value: customerId }] : [];
      const result = await customerMeasurementService.getMany(filters as any, {}, SHOP_ID);
      if (result.success && result.data) {
        return convertFirebaseToLocal(result.data.data);
      }
    }
    return getMockMeasurements(customerId);
  }

  // Shop Profile
  static async getShopProfile(): Promise<ShopProfile> {
    if (USE_FIREBASE) {
      const result = await shopService.getById(SHOP_ID);
      if (result.success && result.data) {
        return {
          shopName: result.data.shopName,
          email: result.data.email,
          address: result.data.address,
          contact: result.data.contact,
          logoUrl: result.data.logoUrl,
        };
      }
    }
    return getShopProfile();
  }

  // Settings
  static async getAppearanceSettings(): Promise<AppearanceSettings> {
    if (USE_FIREBASE) {
      const result = await appearanceSettingsService.getMany([], {}, SHOP_ID);
      if (result.success && result.data && result.data.data.length > 0) {
        const settings = result.data.data[0];
        return {
          theme: settings.theme,
          font: settings.font,
        };
      }
    }
    return getAppearanceSettings();
  }

  static async getNotificationSettings(): Promise<NotificationSettings> {
    if (USE_FIREBASE) {
      const result = await notificationSettingsService.getMany([], {}, SHOP_ID);
      if (result.success && result.data && result.data.data.length > 0) {
        return result.data.data[0];
      }
    }
    return getNotificationSettings();
  }

  // Real-time listeners (Firebase only)
  static onCustomersChange(callback: (customers: Customer[]) => void): () => void {
    if (USE_FIREBASE) {
      return customerService.onCollectionChange(
        (data) => callback(convertFirebaseToLocal(data)),
        [],
        SHOP_ID
      );
    }
    // For localStorage, we can simulate with storage events
    const handler = () => {
      callback(getMockCustomers());
    };
    window.addEventListener('storage', handler);
    return () => window.removeEventListener('storage', handler);
  }

  static onOrdersChange(callback: (orders: Order[]) => void): () => void {
    if (USE_FIREBASE) {
      return orderService.onCollectionChange(
        (data) => callback(convertFirebaseToLocal(data)),
        [],
        SHOP_ID
      );
    }
    const handler = () => {
      callback(getMockOrders());
    };
    window.addEventListener('storage', handler);
    return () => window.removeEventListener('storage', handler);
  }

  // Utility methods
  static async isFirebaseEnabled(): Promise<boolean> {
    return USE_FIREBASE;
  }

  static async testConnection(): Promise<boolean> {
    if (USE_FIREBASE) {
      try {
        const result = await customerService.getMany([], { limit: 1 }, SHOP_ID);
        return result.success;
      } catch {
        return false;
      }
    }
    return true; // localStorage is always available
  }
}

// Export convenience functions
export const getCustomers = () => DatabaseAdapter.getCustomers();
export const getOrders = () => DatabaseAdapter.getOrders();
export const getInventory = () => DatabaseAdapter.getInventory();
export const getTailoringItems = () => DatabaseAdapter.getTailoringItems();
export const getEmployees = () => DatabaseAdapter.getEmployees();
export const getIncomeTransactions = () => DatabaseAdapter.getIncomeTransactions();
export const getExpenseTransactions = () => DatabaseAdapter.getExpenseTransactions();
export const getCustomerMeasurements = (customerId?: string) => DatabaseAdapter.getCustomerMeasurements(customerId);
export const getShopProfileAsync = () => DatabaseAdapter.getShopProfile();
export const getAppearanceSettingsAsync = () => DatabaseAdapter.getAppearanceSettings();
export const getNotificationSettingsAsync = () => DatabaseAdapter.getNotificationSettings();

// Real-time listeners
export const onCustomersChange = (callback: (customers: Customer[]) => void) => DatabaseAdapter.onCustomersChange(callback);
export const onOrdersChange = (callback: (orders: Order[]) => void) => DatabaseAdapter.onOrdersChange(callback);
