import { db } from '../db/db_index';
import { storeInfo, productInfo } from '../db/schema';
import { eq, inArray } from 'drizzle-orm';

export interface Store {
  id: number;
  name: string;
  description: string | null;
  imageUrl: string | null;
  owner: number;
  createdAt: Date;
  updatedAt: Date;
}

export async function getAllStores(): Promise<any[]> {
  const stores = await db.query.storeInfo.findMany({
    with: {
      owner: true,
    },
  });

  return stores;
}

export async function getStoreById(id: number): Promise<any | null> {
  const store = await db.query.storeInfo.findFirst({
    where: eq(storeInfo.id, id),
    with: {
      owner: true,
    },
  });

  return store || null;
}

export interface CreateStoreInput {
  name: string;
  description?: string;
  imageUrl?: string;
  owner: number;
}

export async function createStore(
  input: CreateStoreInput,
  products?: number[]
): Promise<Store> {
  const [newStore] = await db
    .insert(storeInfo)
    .values({
      name: input.name,
      description: input.description,
      imageUrl: input.imageUrl,
      owner: input.owner,
    })
    .returning();

  // Assign selected products to this store
  if (products && products.length > 0) {
    await db
      .update(productInfo)
      .set({ storeId: newStore.id })
      .where(inArray(productInfo.id, products));
  }

  return {
    id: newStore.id,
    name: newStore.name,
    description: newStore.description,
    imageUrl: newStore.imageUrl,
    owner: newStore.owner,
    createdAt: newStore.createdAt,
    updatedAt: newStore.createdAt,
  };
}

export interface UpdateStoreInput {
  name?: string;
  description?: string;
  imageUrl?: string;
  owner?: number;
}

export async function updateStore(
  id: number,
  input: UpdateStoreInput,
  products?: number[]
): Promise<Store> {
  const [updatedStore] = await db
    .update(storeInfo)
    .set({
      ...input,
    })
    .where(eq(storeInfo.id, id))
    .returning();

  if (!updatedStore) {
    throw new Error("Store not found");
  }

  // Update products if provided
  if (products !== undefined) {
    // First, set storeId to null for products not in the list but currently assigned to this store
    await db
      .update(productInfo)
      .set({ storeId: null })
      .where(eq(productInfo.storeId, id));

    // Then, assign the selected products to this store
    if (products.length > 0) {
      await db
        .update(productInfo)
        .set({ storeId: id })
        .where(inArray(productInfo.id, products));
    }
  }

  return {
    id: updatedStore.id,
    name: updatedStore.name,
    description: updatedStore.description,
    imageUrl: updatedStore.imageUrl,
    owner: updatedStore.owner,
    createdAt: updatedStore.createdAt,
    updatedAt: updatedStore.createdAt,
  };
}

export async function deleteStore(id: number): Promise<{ message: string }> {
  return await db.transaction(async (tx) => {
    // First, update all products of this store to set storeId to null
    await tx
      .update(productInfo)
      .set({ storeId: null })
      .where(eq(productInfo.storeId, id));

    // Then delete the store
    const [deletedStore] = await tx
      .delete(storeInfo)
      .where(eq(storeInfo.id, id))
      .returning();

    if (!deletedStore) {
      throw new Error("Store not found");
    }

    return {
      message: "Store deleted successfully",
    };
  });
}
