/**
 * Club effect interpreter.
 *
 * Only place where DB writes are invoked for the club aggregate.
 */

import { eq, and } from 'drizzle-orm';
import type { DrizzleClient } from '@/server/db/client.js';
import * as clubQueries from '@/server/db/queries/club.js';
import { clubMemberships } from '@/server/db/schema.js';
import type { ClubEffect } from './effects.js';

export interface ApplyClubDeps {
  db: DrizzleClient;
}

export interface ApplyClubResult {
  membershipId?: string;
  isNewMembership?: boolean;
}

export async function applyEffects(
  deps: ApplyClubDeps,
  effects: ClubEffect[],
): Promise<ApplyClubResult> {
  const { db } = deps;
  const result: ApplyClubResult = {};

  for (const eff of effects) {
    switch (eff.kind) {
      case 'create-membership': {
        const membership = await clubQueries.ensureMembership(
          db,
          eff.userId,
          eff.vendorId,
          eff.joinedViaOrderLineId,
        );
        result.membershipId = membership.id;
        result.isNewMembership = true;
        break;
      }
      case 'reactivate-membership': {
        await db
          .update(clubMemberships)
          .set({ isActive: true })
          .where(eq(clubMemberships.id, eff.membershipId));
        result.membershipId = eff.membershipId;
        result.isNewMembership = false;
        break;
      }
      case 'noop-membership': {
        result.membershipId = eff.membershipId;
        result.isNewMembership = false;
        break;
      }
    }
  }

  return result;
}

/** Read helper used by the orchestrator before deciding a membership transition. */
export async function loadMembershipContextRow(
  db: DrizzleClient,
  userId: string,
  vendorId: string,
) {
  const [row] = await db
    .select()
    .from(clubMemberships)
    .where(and(eq(clubMemberships.userId, userId), eq(clubMemberships.vendorId, vendorId)))
    .limit(1);
  return row ?? null;
}
