import { db } from '../db/client.js';
import type { DailyEducationQuestion, DailyEducationRow, EducationQuestionRow } from '../types.js';

export const getEducationOptOut = async (userId: string) => {
  const result = await db.query<{ education_opt_out: boolean }>(
    `SELECT education_opt_out
     FROM users
     WHERE id = $1`,
    [userId],
  );

  return result.rows[0]?.education_opt_out ?? false;
};

export const updateEducationOptOut = async (userId: string, educationOptOut: boolean) => {
  const result = await db.query<{ education_opt_out: boolean }>(
    `UPDATE users
     SET education_opt_out = $2
     WHERE id = $1
     RETURNING education_opt_out`,
    [userId, educationOptOut],
  );

  return result.rows[0]?.education_opt_out ?? educationOptOut;
};

export const getDailyEducationForDate = async (publishDate?: string) => {
  const result = publishDate
    ? await db.query<DailyEducationRow>(
        `SELECT id, publish_date::text, fact, quiz_questions, created_by_user_id, created_at, updated_at
         FROM daily_education
         WHERE publish_date = $1`,
        [publishDate],
      )
    : await db.query<DailyEducationRow>(
        `SELECT id, publish_date::text, fact, quiz_questions, created_by_user_id, created_at, updated_at
         FROM daily_education
         WHERE publish_date = CURRENT_DATE`,
      );

  return result.rows[0] ?? null;
};

export const listDailyEducationForAdmin = async () => {
  const result = await db.query<DailyEducationRow>(
    `SELECT id, publish_date::text, fact, quiz_questions, created_by_user_id, created_at, updated_at
     FROM daily_education
     ORDER BY publish_date DESC
     LIMIT 120`,
  );

  return result.rows;
};

export const upsertDailyEducation = async ({
  publishDate,
  fact,
  createdByUserId,
}: {
  publishDate: string;
  fact: string;
  createdByUserId: string;
}) => {
  const result = await db.query<DailyEducationRow>(
    `INSERT INTO daily_education (publish_date, fact, created_by_user_id)
     VALUES ($1, $2, $3)
     ON CONFLICT (publish_date) DO UPDATE
     SET fact = EXCLUDED.fact,
         updated_at = CURRENT_TIMESTAMP
     RETURNING id, publish_date::text, fact, quiz_questions, created_by_user_id, created_at, updated_at`,
    [publishDate, fact, createdByUserId],
  );

  return result.rows[0];
};

export const listEducationQuestionsForAdmin = async () => {
  const result = await db.query<EducationQuestionRow>(
    `SELECT id, prompt, options, correct_answer_index, explanation, created_by_user_id, created_at, updated_at
     FROM education_question_bank
     ORDER BY updated_at DESC, created_at DESC
     LIMIT 400`,
  );

  return result.rows;
};

export const listDailyEducationQuestions = async (seedDate?: string) => {
  const result = await db.query<EducationQuestionRow>(
     `SELECT id, prompt, options, correct_answer_index, explanation, created_by_user_id, created_at, updated_at
     FROM education_question_bank
     ORDER BY md5(COALESCE($1::text, CURRENT_DATE::text) || id::text)
     LIMIT 4`,
    [seedDate ?? null],
  );

  return result.rows;
};

export const createEducationQuestion = async ({
  question,
  createdByUserId,
}: {
  question: DailyEducationQuestion;
  createdByUserId: string;
}) => {
  const result = await db.query<EducationQuestionRow>(
    `INSERT INTO education_question_bank (prompt, options, correct_answer_index, explanation, created_by_user_id)
     VALUES ($1, $2::jsonb, $3, $4, $5)
     RETURNING id, prompt, options, correct_answer_index, explanation, created_by_user_id, created_at, updated_at`,
    [question.prompt, JSON.stringify(question.options), question.correctAnswerIndex, question.explanation, createdByUserId],
  );

  return result.rows[0];
};

export const updateEducationQuestion = async (questionId: string, question: DailyEducationQuestion) => {
  const result = await db.query<EducationQuestionRow>(
    `UPDATE education_question_bank
     SET prompt = $2,
         options = $3::jsonb,
         correct_answer_index = $4,
         explanation = $5,
         updated_at = CURRENT_TIMESTAMP
     WHERE id = $1
     RETURNING id, prompt, options, correct_answer_index, explanation, created_by_user_id, created_at, updated_at`,
    [questionId, question.prompt, JSON.stringify(question.options), question.correctAnswerIndex, question.explanation],
  );

  return result.rows[0] ?? null;
};

export const deleteEducationQuestion = async (questionId: string) => {
  const result = await db.query<{ id: string }>(
    `DELETE FROM education_question_bank
     WHERE id = $1
     RETURNING id`,
    [questionId],
  );

  return Boolean(result.rowCount);
};

export const deleteDailyEducation = async (educationId: string) => {
  const result = await db.query<{ id: string }>(
    `DELETE FROM daily_education
     WHERE id = $1
     RETURNING id`,
    [educationId],
  );

  return Boolean(result.rowCount);
};
