import { eq, and, SQL, desc, gte, lte } from "drizzle-orm";
import { getDb } from "coze-coding-dev-sdk";
import { foodRecords, insertFoodRecordSchema } from "./shared/schema";
import type { FoodRecord, InsertFoodRecord } from "./shared/schema";

export class FoodRecordManager {
  async createFoodRecord(data: InsertFoodRecord): Promise<FoodRecord> {
    const db = await getDb();
    const validated = insertFoodRecordSchema.parse(data);
    const [record] = await db.insert(foodRecords).values(validated).returning();
    return record;
  }

  async getFoodRecords(options: {
    userId: string;
    skip?: number;
    limit?: number;
    mealType?: string;
    startDate?: Date;
    endDate?: Date;
  }): Promise<FoodRecord[]> {
    const { userId, skip = 0, limit = 100, mealType, startDate, endDate } = options;
    const db = await getDb();

    const conditions: SQL[] = [];
    conditions.push(eq(foodRecords.userId, userId));

    if (mealType) {
      conditions.push(eq(foodRecords.mealType, mealType));
    }

    if (startDate) {
      conditions.push(gte(foodRecords.recordedAt, startDate));
    }

    if (endDate) {
      conditions.push(lte(foodRecords.recordedAt, endDate));
    }

    let query = db.select().from(foodRecords).$dynamic();

    if (conditions.length > 0) {
      query = query.where(and(...conditions));
    }

    return query.orderBy(desc(foodRecords.recordedAt)).limit(limit).offset(skip);
  }

  async getFoodRecordById(id: string): Promise<FoodRecord | null> {
    const db = await getDb();
    const [record] = await db.select().from(foodRecords).where(eq(foodRecords.id, id));
    return record || null;
  }

  async deleteFoodRecord(id: string): Promise<boolean> {
    const db = await getDb();
    const result = await db.delete(foodRecords).where(eq(foodRecords.id, id));
    return (result.rowCount ?? 0) > 0;
  }

  async getTotalCaloriesByDate(userId: string, date: Date): Promise<number> {
    const db = await getDb();
    const startOfDay = new Date(date);
    startOfDay.setHours(0, 0, 0, 0);

    const endOfDay = new Date(date);
    endOfDay.setHours(23, 59, 59, 999);

    const records = await db
      .select()
      .from(foodRecords)
      .where(
        and(
          eq(foodRecords.userId, userId),
          gte(foodRecords.recordedAt, startOfDay),
          lte(foodRecords.recordedAt, endOfDay)
        )
      );

    return records.reduce((sum, record) => sum + record.calories, 0);
  }
}

export const foodRecordManager = new FoodRecordManager();
