import { pb } from './pb';

// Upsert helper: update existing record if found, otherwise create.
async function pbUpsert(collection, filter, updateData, createData) {
  try {
    const r = await pb.collection(collection).getFirstListItem(filter);
    return pb.collection(collection).update(r.id, updateData);
  } catch {
    return pb.collection(collection).create(createData);
  }
}

// ── Topics ──────────────────────────────────────────────────────────────────

export async function getTopics() {
  return pb.collection('topics').getFullList();
}

export async function saveTopics(topics) {
  const existing = await pb.collection('topics').getFullList({ fields: 'id' });
  for (const r of existing) {
    await pb.collection('topics').delete(r.id, { requestKey: null });
  }
  for (const t of topics) {
    await pb.collection('topics').create({
      id: t.id,
      label: t.label,
      type: t.type,
      description: t.description,
      learning_relevance: t.learning_relevance || 'standard',
      relevance_locked: t.relevance_locked === true,
    }, { requestKey: null });
  }
}

export async function upsertTopic(topic) {
  try {
    await pb.collection('topics').getOne(topic.id);
    return await pb.collection('topics').update(topic.id, topic);
  } catch {
    return await pb.collection('topics').create({ 
      id: topic.id, 
      learning_relevance: 'standard',
      ...topic 
    });
  }
}

// ── Relations ────────────────────────────────────────────────────────────────

export async function getRelations() {
  return pb.collection('relations').getFullList();
}

export async function saveRelations(relations) {
  const existing = await pb.collection('relations').getFullList({ fields: 'id' });
  for (const r of existing) {
    await pb.collection('relations').delete(r.id, { requestKey: null });
  }
  for (const r of relations) {
    await pb.collection('relations').create(r, { requestKey: null });
  }
}

export async function addRelation(relation) {
  return pb.collection('relations').create(relation);
}

export async function removeRelation(source, target, type) {
  const records = await pb.collection('relations').getFullList({
    filter: `source="${source}" && target="${target}" && type="${type}"`,
  });
  return Promise.all(records.map(r => pb.collection('relations').delete(r.id, { requestKey: null })));
}

// ── Content ──────────────────────────────────────────────────────────────────

export async function getContent(topicId) {
  try {
    const r = await pb.collection('content').getFirstListItem(`topic_id="${topicId}"`);
    return r.data;
  } catch { return null; }
}

export function setContent(topicId, data) {
  return pbUpsert('content', `topic_id="${topicId}"`, { data }, { topic_id: topicId, data });
}

export async function deleteContent(topicId) {
  try {
    const r = await pb.collection('content').getFirstListItem(`topic_id="${topicId}"`);
    return pb.collection('content').delete(r.id);
  } catch { /* no record, nothing to do */ }
}

// ── Quiz Banks ───────────────────────────────────────────────────────────────

function normalizeQuizQuestion(q) {
  if (!q || typeof q !== 'object') return q;
  return q.difficulty ? q : { ...q, difficulty: 'medium' };
}

export async function getQuizBank(topicId) {
  try {
    const r = await pb.collection('quiz_banks').getFirstListItem(`topic_id="${topicId}"`);
    return (r.questions || []).map(normalizeQuizQuestion);
  } catch { return []; }
}

export function setQuizBank(topicId, questions) {
  return pbUpsert('quiz_banks', `topic_id="${topicId}"`, { questions }, { topic_id: topicId, questions });
}

export async function deleteQuestionFromBank(topicId, questionId) {
  const questions = await getQuizBank(topicId);
  return setQuizBank(topicId, questions.filter(q => q.id !== questionId));
}

// ── Sources ──────────────────────────────────────────────────────────────────

export async function getSources() {
  return pb.collection('sources').getFullList();
}

export async function addSource(source) {
  return pb.collection('sources').create(source);
}

export async function updateSourceStatus(id, status, error = '') {
  return pb.collection('sources').update(id, { status, error });
}

export async function deleteSource(id) {
  return pb.collection('sources').delete(id);
}

// ── Team Members ─────────────────────────────────────────────────────────────

export async function getTeamMembers() {
  return pb.collection('team_members').getFullList();
}

export async function addTeamMember(member) {
  return pb.collection('team_members').create(member);
}

export async function updateTeamMember(id, data) {
  return pb.collection('team_members').update(id, data);
}

export async function deleteTeamMember(id) {
  return pb.collection('team_members').delete(id);
}

// ── Quiz Results ─────────────────────────────────────────────────────────────

export async function getQuizResult(userId, weekNumber) {
  try {
    return await pb.collection('quiz_results').getFirstListItem(
      `user_id="${userId}" && week_number=${weekNumber}`
    );
  } catch { return null; }
}

export async function saveQuizResult(userId, weekNumber, result) {
  return pb.collection('quiz_results').create({
    user_id: userId,
    week_number: weekNumber,
    score: result.score,
    total: result.total,
    percentage: result.percentage,
    time_used: result.timeUsed,
    completed_at: result.completedAt,
    breakdown: result.breakdown,
    points_earned: result.pointsEarned,
  });
}

// ── Quiz Cache ────────────────────────────────────────────────────────────────

export async function getCachedQuiz(userId, weekNumber) {
  try {
    return await pb.collection('quiz_cache').getFirstListItem(
      `user_id="${userId}" && week_number=${weekNumber}`
    );
  } catch { return null; }
}

export function setCachedQuiz(userId, weekNumber, quiz) {
  const data = { questions: quiz.questions, meta: quiz.meta };
  return pbUpsert('quiz_cache', `user_id="${userId}" && week_number=${weekNumber}`,
    data, { user_id: userId, week_number: weekNumber, ...data });
}

// ── Learn Progress ────────────────────────────────────────────────────────────

export async function getLearnDone(userId, weekNumber) {
  try {
    const r = await pb.collection('learn_progress').getFirstListItem(
      `user_id="${userId}" && week_number=${weekNumber}`
    );
    return r.done;
  } catch { return false; }
}

export function setLearnDone(userId, weekNumber) {
  return pbUpsert('learn_progress', `user_id="${userId}" && week_number=${weekNumber}`,
    { done: true }, { user_id: userId, week_number: weekNumber, done: true });
}

// ── Leaderboard ───────────────────────────────────────────────────────────────

export async function getLeaderboard() {
  const entries = await pb.collection('leaderboard').getFullList();
  return entries.sort((a, b) => (b.points || 0) - (a.points || 0));
}

export async function upsertLeaderboardEntry(userId, name, pointsDelta, testsCompletedDelta = 0) {
  try {
    const r = await pb.collection('leaderboard').getFirstListItem(`user_id="${userId}"`);
    return pb.collection('leaderboard').update(r.id, {
      points: (r.points || 0) + pointsDelta,
      tests_completed: (r.tests_completed || 0) + testsCompletedDelta,
    });
  } catch {
    return pb.collection('leaderboard').create({
      user_id: userId,
      name,
      points: pointsDelta,
      tests_completed: testsCompletedDelta,
      learnings_completed: 0,
    });
  }
}

// ── Settings ──────────────────────────────────────────────────────────────────

export async function getSetting(key, defaultValue = null) {
  try {
    const r = await pb.collection('settings').getFirstListItem(`key="${key}"`);
    return r.value ?? defaultValue;
  } catch { return defaultValue; }
}

export function setSetting(key, value) {
  return pbUpsert('settings', `key="${key}"`, { value: String(value) }, { key, value: String(value) });
}

// ── Curriculum ────────────────────────────────────────────────────────────────

export async function getCurriculum(year) {
  try {
    return await pb.collection('curriculum').getFullList({
      filter: `year=${year}`,
      sort: 'week_number',
    });
  } catch { return []; }
}

export async function getCurriculumWeek(year, weekNumber) {
  try {
    return await pb.collection('curriculum').getFirstListItem(
      `year=${year} && week_number=${weekNumber}`
    );
  } catch { return null; }
}

export function setCurriculumWeek(year, weekNumber, data) {
  return pbUpsert('curriculum', `year=${year} && week_number=${weekNumber}`,
    data, { year, week_number: weekNumber, ...data });
}

export async function deleteCurriculumWeek(year, weekNumber) {
  try {
    const r = await pb.collection('curriculum').getFirstListItem(
      `year=${year} && week_number=${weekNumber}`
    );
    return pb.collection('curriculum').delete(r.id);
  } catch { /* nothing to delete */ }
}

export async function bulkSetCurriculum(year, weeks) {
  // Delete all existing entries for this year first
  const existing = await getCurriculum(year);
  await Promise.all(
    existing.map(r => pb.collection('curriculum').delete(r.id, { requestKey: null }))
  );
  // Create all new entries
  return Promise.all(
    weeks.map(w => pb.collection('curriculum').create({
      year,
      week_number: w.week_number,
      topic_id: w.topic_id || '',
      theme: w.theme || '',
      quarter: w.quarter || Math.ceil(w.week_number / 13),
      is_review_week: w.is_review_week || false,
      sort_order: w.sort_order ?? w.week_number,
    }, { requestKey: null }))
  );
}

// ── Reset for Smoke Testing ──────────────────────────────────────────────────

/**
 * Truncate the collections that hold AI-generated and progress data.
 *
 * Order matters: rows that reference `topics.id` (relations, content,
 * quiz_banks) are deleted before topics themselves so we never leave
 * dangling references mid-wipe.
 *
 * `team_members`, `settings`, and `llm_calls` are intentionally preserved.
 *
 * @param {{ includeProgress?: boolean }} [opts]
 * @returns {Promise<Array<{collection: string, deleted: number, error?: string}>>}
 */
export async function resetForSmokeTest({
  includeProgress = false,
} = {}) {
  const collections = [
    'relations',
    'content',
    'quiz_banks',
    'quiz_results',
    'quiz_cache',
    'curriculum',
    'sources',
    'topics',
  ];
  if (includeProgress) collections.push('learn_progress', 'leaderboard');

  const results = [];
  for (const name of collections) {
    try {
      const rows = await pb.collection(name).getFullList({ fields: 'id', requestKey: null });
      // Sequential deletes — bulk delete-many isn't in the JS SDK and parallel
      // deletes on the same collection sometimes 409 in PocketBase.
      let deleted = 0;
      for (const r of rows) {
        await pb.collection(name).delete(r.id, { requestKey: null });
        deleted++;
      }
      results.push({ collection: name, deleted });
    } catch (err) {
      results.push({ collection: name, deleted: 0, error: err?.message || String(err) });
    }
  }
  return results;
}


