import { Op, Sequelize, ModelStatic, Model } from 'sequelize';

import { TableRetentionPolicy } from './config';

export type ArchiveQueryPlan = {
  where: Record<string, any>;
  dateField: string;
};

export function getArchiveDateField(model: ModelStatic<Model>): string {
  const attributes = model.rawAttributes;
  if (attributes.updated_at) {
    return 'updated_at';
  }
  if (attributes.created_at) {
    return 'created_at';
  }
  return 'created_at';
}

export function buildArchiveQueryPlan(
  model: ModelStatic<Model>,
  policy: TableRetentionPolicy,
  cutoffDate: Date
): ArchiveQueryPlan {
  const dateField = getArchiveDateField(model);
  const where: any = {
    [dateField]: { [Op.lte]: cutoffDate },
  };

  const conditions: any[] = [];

  if (model.rawAttributes.status) {
    if (policy.archivableStatuses && policy.archivableStatuses.length > 0) {
      conditions.push({ status: { [Op.in]: policy.archivableStatuses } });
    }

    if (policy.excludeConditions?.statuses && policy.excludeConditions.statuses.length > 0) {
      conditions.push({ status: { [Op.notIn]: policy.excludeConditions.statuses } });
    }
  }

  if (policy.excludeConditions?.customCondition) {
    // customCondition is an EXCLUSION condition: records matching it are KEPT (not archived).
    // E.g. customCondition='pending_webhooks > 0' means "exclude records with pending webhooks".
    // We wrap with NOT() so the query selects records that do NOT match the exclusion.
    conditions.push(Sequelize.literal(`NOT (${policy.excludeConditions.customCondition})`));
  }

  if (conditions.length > 0) {
    where[Op.and] = conditions;
  }

  return { where, dateField };
}
