import { db } from '../../config/database.js';
import { kurzy } from '../../db/schema.js';
import { eq, sql, asc } from 'drizzle-orm';
import { NotFoundError } from '../../utils/errors.js';

export const getAllKurzy = async () => {
  const result = await db
    .select({
      id: kurzy.id,
      nazov: kurzy.nazov,
      typKurzu: kurzy.typKurzu,
      popis: kurzy.popis,
      cena: kurzy.cena,
      maxKapacita: kurzy.maxKapacita,
      aktivny: kurzy.aktivny,
      farba: kurzy.farba,
      datumOd: kurzy.datumOd,
      datumDo: kurzy.datumDo,
      createdAt: kurzy.createdAt,
      registraciiCount: sql`(SELECT COUNT(*) FROM registracie WHERE kurz_id = ${kurzy.id})::int`,
    })
    .from(kurzy)
    .orderBy(asc(kurzy.nazov));

  return result;
};

export const getKurzById = async (id) => {
  const [kurz] = await db
    .select()
    .from(kurzy)
    .where(eq(kurzy.id, id))
    .limit(1);

  if (!kurz) {
    throw new NotFoundError('Kurz nenájdený');
  }

  return kurz;
};

export const createKurz = async (data) => {
  const [newKurz] = await db
    .insert(kurzy)
    .values({
      nazov: data.nazov,
      typKurzu: data.typKurzu,
      popis: data.popis || null,
      cena: data.cena,
      maxKapacita: data.maxKapacita || null,
      aktivny: data.aktivny !== undefined ? data.aktivny : true,
      farba: data.farba || null,
      datumOd: data.datumOd ? new Date(data.datumOd) : null,
      datumDo: data.datumDo ? new Date(data.datumDo) : null,
    })
    .returning();

  return newKurz;
};

export const updateKurz = async (id, data) => {
  await getKurzById(id);

  const updateData = {
    nazov: data.nazov,
    typKurzu: data.typKurzu,
    popis: data.popis !== undefined ? data.popis : undefined,
    cena: data.cena,
    maxKapacita: data.maxKapacita !== undefined ? data.maxKapacita : undefined,
    aktivny: data.aktivny !== undefined ? data.aktivny : undefined,
    farba: data.farba !== undefined ? data.farba : undefined,
    datumOd: data.datumOd !== undefined ? (data.datumOd ? new Date(data.datumOd) : null) : undefined,
    datumDo: data.datumDo !== undefined ? (data.datumDo ? new Date(data.datumDo) : null) : undefined,
    updatedAt: new Date(),
  };

  Object.keys(updateData).forEach(key => {
    if (updateData[key] === undefined) {
      delete updateData[key];
    }
  });

  const [updated] = await db
    .update(kurzy)
    .set(updateData)
    .where(eq(kurzy.id, id))
    .returning();

  return updated;
};

export const deleteKurz = async (id) => {
  await getKurzById(id);
  await db.delete(kurzy).where(eq(kurzy.id, id));
  return { success: true, message: 'Kurz bol odstránený' };
};

export const getKurzyStats = async () => {
  const [stats] = await db
    .select({
      totalKurzy: sql`(SELECT COUNT(*) FROM kurzy)::int`,
      aktivneKurzy: sql`(SELECT COUNT(*) FROM kurzy WHERE aktivny = true)::int`,
      totalUcastnici: sql`(SELECT COUNT(*) FROM ucastnici)::int`,
      totalRegistracie: sql`(SELECT COUNT(*) FROM registracie)::int`,
      zaplateneRegistracie: sql`(SELECT COUNT(*) FROM registracie WHERE zaplatene = true)::int`,
      absolvovaneRegistracie: sql`(SELECT COUNT(*) FROM registracie WHERE stav = 'absolvoval')::int`,
    })
    .from(sql`(SELECT 1) AS dummy`);

  return stats;
};
