import { and, eq } from 'drizzle-orm';
import type { DrizzleClient } from '@/server/db/client.js';
import { dealTranslations, dealSlugRedirects } from '@/server/db/schema.js';

export type TranslationField = 'title' | 'description' | 'specialInstructions';

export async function upsertDealTranslationField(
  db: DrizzleClient,
  input: {
    dealId: string;
    locale: string;
    slug: string;
    field: TranslationField;
    translatedText: string;
    sourceHash: string;
    modelId: string;
  },
): Promise<void> {
  const now = new Date();
  const field = input.field;
  const values = {
    dealId: input.dealId,
    locale: input.locale,
    slug: input.slug,
    title: field === 'title' ? input.translatedText : '',
    description: field === 'description' ? input.translatedText : '',
    pickupAddress: '',
    titleSourceHash: field === 'title' ? input.sourceHash : '',
    descriptionSourceHash: field === 'description' ? input.sourceHash : '',
    ...(field === 'specialInstructions'
      ? {
          specialInstructions: input.translatedText,
          specialInstructionsSourceHash: input.sourceHash,
        }
      : {}),
    modelId: input.modelId,
    status: 'OK' as const,
    translatedAt: now,
  };
  const set =
    field === 'title'
      ? { title: input.translatedText, titleSourceHash: input.sourceHash }
      : field === 'description'
        ? { description: input.translatedText, descriptionSourceHash: input.sourceHash }
        : {
            specialInstructions: input.translatedText,
            specialInstructionsSourceHash: input.sourceHash,
          };
  await db
    .insert(dealTranslations)
    .values(values)
    .onConflictDoUpdate({
      target: [dealTranslations.dealId, dealTranslations.locale],
      set: { ...set, modelId: input.modelId, status: 'OK', translatedAt: now, updatedAt: now },
    });
}

export async function pinDealTranslationSlug(
  db: DrizzleClient,
  input: {
    dealId: string;
    locale: string;
    slug: string;
  },
): Promise<void> {
  const now = new Date();
  const updated = await db
    .update(dealTranslations)
    .set({ slug: input.slug, updatedAt: now })
    .where(
      and(eq(dealTranslations.dealId, input.dealId), eq(dealTranslations.locale, input.locale)),
    )
    .returning({ id: dealTranslations.id });
  if (updated.length === 0) {
    await db
      .insert(dealTranslations)
      .values({
        dealId: input.dealId,
        locale: input.locale,
        slug: input.slug,
        title: '',
        description: '',
        pickupAddress: '',
        titleSourceHash: '',
        descriptionSourceHash: '',
        status: 'OK',
        createdAt: now,
        updatedAt: now,
      })
      .onConflictDoNothing();
  }
}

export async function fillSourceTranslation(
  db: DrizzleClient,
  input: {
    dealId: string;
    locale: string;
    title: string;
    description: string;
  },
): Promise<void> {
  await db
    .update(dealTranslations)
    .set({ title: input.title, description: input.description, updatedAt: new Date() })
    .where(
      and(eq(dealTranslations.dealId, input.dealId), eq(dealTranslations.locale, input.locale)),
    );
}

export async function evictDealTranslationField(
  db: DrizzleClient,
  input: {
    dealId: string;
    locale: string;
    hashField: 'titleSourceHash' | 'descriptionSourceHash' | 'specialInstructionsSourceHash';
  },
): Promise<void> {
  await db
    .update(dealTranslations)
    .set({ [input.hashField]: null, status: 'STALE', updatedAt: new Date() })
    .where(
      and(eq(dealTranslations.dealId, input.dealId), eq(dealTranslations.locale, input.locale)),
    );
}

export async function regenerateDealTranslationSlug(
  db: DrizzleClient,
  input: {
    dealId: string;
    locale: string;
    oldSlug: string;
  },
): Promise<void> {
  await db
    .insert(dealSlugRedirects)
    .values({ dealId: input.dealId, locale: input.locale, oldSlug: input.oldSlug })
    .onConflictDoNothing();
  await db
    .update(dealTranslations)
    .set({
      slug: null as unknown as string,
      titleSourceHash: null as unknown as string,
      updatedAt: new Date(),
    })
    .where(
      and(eq(dealTranslations.dealId, input.dealId), eq(dealTranslations.locale, input.locale)),
    );
}
