import { RegimenModel } from '../../schemas/regimen.schema.js';

interface FindByHouseholdQuery {
  isActive?: boolean;
  cursor?: string;
  limit: number;
}

interface RegimenMedicationData {
  medicineId: string;
  medicineName: string;
  medicineStrength: number;
  medicineStrengthUnit: string;
  medicineForm: string;
  dosage: number;
  dosageUnit: string;
  frequency: string;
  customFrequencyPerDay?: number;
  timeOfDay?: string;
  instructions?: string;
}

interface CreateRegimenData {
  name: string;
  isActive: boolean;
  medications: RegimenMedicationData[];
}

interface UpdateRegimenData {
  name?: string;
  isActive?: boolean;
  medications?: RegimenMedicationData[];
}

export class RegimensRepository {
  public async findByHousehold(householdId: string, userId: string, query: FindByHouseholdQuery) {
    const filter: Record<string, unknown> = { householdId, userId, isDeleted: false };

    if (query.isActive !== undefined) filter['isActive'] = query.isActive;

    if (query.cursor) {
      const id = Buffer.from(query.cursor, 'base64').toString();
      filter['_id'] = { $gt: id };
    }

    const limit = query.limit;
    const items = await RegimenModel.find(filter)
      .sort({ name: 1, _id: 1 })
      .limit(limit + 1)
      .lean()
      .exec();

    const hasMore = items.length > limit;
    const data = hasMore ? items.slice(0, limit) : items;
    const cursor =
      data.length > 0 ? Buffer.from(data[data.length - 1]._id.toString()).toString('base64') : null;

    return { data, pagination: { cursor: hasMore ? cursor : null, hasMore } };
  }

  public async findById(id: string, householdId: string, userId: string) {
    return RegimenModel.findOne({ _id: id, householdId, userId, isDeleted: false }).lean().exec();
  }

  public async findActiveByUser(householdId: string, userId: string) {
    return RegimenModel.find({ householdId, userId, isActive: true, isDeleted: false })
      .sort({ name: 1, _id: 1 })
      .lean()
      .exec();
  }

  public async create(
    data: CreateRegimenData,
    householdId: string,
    userId: string,
    createdBy: string,
  ) {
    const regimen = new RegimenModel({ ...data, householdId, userId, createdBy });
    const saved = await regimen.save();
    return saved.toObject();
  }

  public async update(id: string, householdId: string, userId: string, data: UpdateRegimenData) {
    return RegimenModel.findOneAndUpdate(
      { _id: id, householdId, userId, isDeleted: false },
      { $set: data },
      { new: true, lean: true },
    ).exec();
  }

  public async softDelete(id: string, householdId: string, userId: string) {
    return RegimenModel.findOneAndUpdate(
      { _id: id, householdId, userId, isDeleted: false },
      { $set: { isDeleted: true } },
      { new: true, lean: true },
    ).exec();
  }
}
