import { initializeApp } from "firebase/app";
import { 
  getFirestore, 
  collection, 
  getDocs, 
  doc, 
  setDoc, 
  getDoc, 
  deleteDoc
} from "firebase/firestore";
import fs from "fs";
import path from "path";
import { Property, Booking, UserAccount, Mechanic, EmergencySubscription } from "../types";

// Load Firebase applet configuration
const configPath = path.join(process.cwd(), "firebase-applet-config.json");
let firebaseConfig: any = {};

if (fs.existsSync(configPath)) {
  try {
    firebaseConfig = JSON.parse(fs.readFileSync(configPath, "utf-8"));
    console.log("Firebase Applet configuration loaded successfully.");
  } catch (error) {
    console.error("Error reading or parsing firebase-applet-config.json:", error);
  }
} else {
  console.warn("firebase-applet-config.json does not exist. Using empty config fallback.");
}

// Ensure databaseId is map-routed correctly in client options if present
const appOptions: any = {
  apiKey: firebaseConfig.apiKey,
  authDomain: firebaseConfig.authDomain,
  projectId: firebaseConfig.projectId,
  storageBucket: firebaseConfig.storageBucket,
  messagingSenderId: firebaseConfig.messagingSenderId,
  appId: firebaseConfig.appId,
};

// Initialize Firebase SDK
const app = initializeApp(appOptions);
const db = firebaseConfig.firestoreDatabaseId 
  ? getFirestore(app, firebaseConfig.firestoreDatabaseId) 
  : getFirestore(app);

// Collection References
const USERS_COLL = "users";
const PROPERTIES_COLL = "properties";
const BOOKINGS_COLL = "bookings";
const MECHANICS_COLL = "mechanics";
const REPAIRS_COLL = "repairBookings";
const SUBS_COLL = "emergencySubs";

// --- DATABASE OPERATIONS WRAPPERS ---

/**
 * Users / Auth Database Operations
 */
export async function dbGetUsers(): Promise<UserAccount[]> {
  try {
    const snap = await getDocs(collection(db, USERS_COLL));
    const list: UserAccount[] = [];
    snap.forEach((d) => {
      list.push(d.data() as UserAccount);
    });
    return list;
  } catch (error) {
    console.error("Failed to query users from Firestore:", error);
    return [];
  }
}

export async function dbGetUserByEmail(email: string): Promise<UserAccount | null> {
  try {
    const formattedEmail = email.toLowerCase().trim();
    const docRef = doc(db, USERS_COLL, formattedEmail);
    const snap = await getDoc(docRef);
    if (snap.exists()) {
      return snap.data() as UserAccount;
    }
    return null;
  } catch (error) {
    console.error(`Failed to get user ${email} from Firestore:`, error);
    return null;
  }
}

export async function dbSaveUser(user: UserAccount): Promise<void> {
  try {
    const formattedEmail = user.email.toLowerCase().trim();
    const docRef = doc(db, USERS_COLL, formattedEmail);
    await setDoc(docRef, {
      ...user,
      email: formattedEmail,
      walletBalance: user.walletBalance ?? 250,
      nextDiscountPercent: user.nextDiscountPercent ?? 0,
      rewardsHistory: user.rewardsHistory ?? []
    });
  } catch (error) {
    console.error(`Failed to save user ${user.email}:`, error);
    throw error;
  }
}

/**
 * Properties Database Operations
 */
export async function dbGetProperties(): Promise<Property[]> {
  try {
    const snap = await getDocs(collection(db, PROPERTIES_COLL));
    const list: Property[] = [];
    snap.forEach((d) => {
      list.push(d.data() as Property);
    });
    return list;
  } catch (error) {
    console.error("Failed to query properties from Firestore:", error);
    return [];
  }
}

export async function dbSaveProperty(property: Property): Promise<void> {
  try {
    const docRef = doc(db, PROPERTIES_COLL, property.id);
    await setDoc(docRef, property);
  } catch (error) {
    console.error(`Failed to save property ${property.id}:`, error);
    throw error;
  }
}

export async function dbDeleteProperty(id: string): Promise<void> {
  try {
    const docRef = doc(db, PROPERTIES_COLL, id);
    await deleteDoc(docRef);
  } catch (error) {
    console.error(`Failed to delete property ${id}:`, error);
    throw error;
  }
}

/**
 * Bookings Database Operations
 */
export async function dbGetBookings(): Promise<Booking[]> {
  try {
    const snap = await getDocs(collection(db, BOOKINGS_COLL));
    const list: Booking[] = [];
    snap.forEach((d) => {
      list.push(d.data() as Booking);
    });
    return list.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime());
  } catch (error) {
    console.error("Failed to query bookings from Firestore:", error);
    return [];
  }
}

export async function dbSaveBooking(booking: Booking): Promise<void> {
  try {
    const docRef = doc(db, BOOKINGS_COLL, booking.id);
    await setDoc(docRef, booking);
  } catch (error) {
    console.error(`Failed to save booking ${booking.id}:`, error);
    throw error;
  }
}

/**
 * Mechanics Database Operations
 */
export async function dbGetMechanics(): Promise<Mechanic[]> {
  try {
    const snap = await getDocs(collection(db, MECHANICS_COLL));
    const list: Mechanic[] = [];
    snap.forEach((d) => {
      list.push(d.data() as Mechanic);
    });
    return list;
  } catch (error) {
    console.error("Failed to query mechanics from Firestore:", error);
    return [];
  }
}

export async function dbSaveMechanic(mechanic: Mechanic): Promise<void> {
  try {
    const docRef = doc(db, MECHANICS_COLL, mechanic.id);
    await setDoc(docRef, mechanic);
  } catch (error) {
    console.error(`Failed to save mechanic ${mechanic.id}:`, error);
    throw error;
  }
}

export async function dbDeleteMechanic(id: string): Promise<void> {
  try {
    const docRef = doc(db, MECHANICS_COLL, id);
    await deleteDoc(docRef);
  } catch (error) {
    console.error(`Failed to delete mechanic ${id}:`, error);
    throw error;
  }
}

/**
 * Repair Bookings / Emergency Support Operations
 */
export async function dbGetRepairBookings(): Promise<any[]> {
  try {
    const snap = await getDocs(collection(db, REPAIRS_COLL));
    const list: any[] = [];
    snap.forEach((d) => {
      list.push(d.data());
    });
    return list.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime());
  } catch (error) {
    console.error("Failed to query repair bookings:", error);
    return [];
  }
}

export async function dbSaveRepairBooking(repair: any): Promise<void> {
  try {
    const docRef = doc(db, REPAIRS_COLL, repair.id);
    await setDoc(docRef, repair);
  } catch (error) {
    console.error(`Failed to save repair booking ${repair.id}:`, error);
    throw error;
  }
}

export async function dbGetEmergencySubscriptions(): Promise<EmergencySubscription[]> {
  try {
    const snap = await getDocs(collection(db, SUBS_COLL));
    const list: EmergencySubscription[] = [];
    snap.forEach((d) => {
      list.push(d.data() as EmergencySubscription);
    });
    return list;
  } catch (error) {
    console.error("Failed to query emergency subscriptions:", error);
    return [];
  }
}

export async function dbSaveEmergencySubscription(sub: EmergencySubscription): Promise<void> {
  try {
    const docRef = doc(db, SUBS_COLL, sub.id);
    await setDoc(docRef, sub);
  } catch (error) {
    console.error(`Failed to save subscription ${sub.id}:`, error);
    throw error;
  }
}

/**
 * Database Seeder function
 * Seeds properties and mechanics on initial run if empty
 */
export async function seedDatabase(initialProps: Property[], initialMechs: Mechanic[]): Promise<void> {
  try {
    console.log("Ensuring and updating default Bihar locations in Firestore...");
    for (const p of initialProps) {
      await dbSaveProperty(p);
    }

    console.log("Ensuring and updating default Bihar mechanics in Firestore...");
    for (const m of initialMechs) {
      await dbSaveMechanic(m);
    }
  } catch (error) {
    console.warn("Seeding database was interrupted or had warnings:", error);
  }
}
