const PUBLIC_PAGE_LIMIT_KEY = 'public_page_limit';

function asPositiveInteger(value, fallback) {
  const parsed = Number(value);
  if (!Number.isFinite(parsed) || parsed < 1) return fallback;
  return Math.floor(parsed);
}

async function ensureConfigTable(pool) {
  await pool.query(`
    CREATE TABLE IF NOT EXISTS mindspace_config (
      \`key\` VARCHAR(64) PRIMARY KEY,
      value TEXT NOT NULL,
      description VARCHAR(255) NULL,
      updated_at BIGINT NOT NULL
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
  `);
}

export function defaultMindSpaceConfig(env = process.env) {
  return {
    publicPageLimit: asPositiveInteger(env.MINDSPACE_FREE_PUBLIC_PAGE_LIMIT ?? 5, 5),
  };
}

async function readConfigRows(pool) {
  const [rows] = await pool.query(
    'SELECT `key`, value FROM mindspace_config',
  );
  return rows;
}

export async function ensureMindSpaceConfig(pool, { env = process.env, seedDefault = true } = {}) {
  await ensureConfigTable(pool);
  if (!seedDefault) return;
  const [rows] = await pool.query('SELECT COUNT(*) AS count FROM mindspace_config');
  if (Number(rows[0]?.count ?? 0) > 0) return;

  const now = Date.now();
  const defaults = defaultMindSpaceConfig(env);
  await pool.query(
    `INSERT INTO mindspace_config (\`key\`, value, description, updated_at)
     VALUES (?, ?, ?, ?)`,
    [PUBLIC_PAGE_LIMIT_KEY, String(defaults.publicPageLimit), '公开页面数量上限', now],
  );
}

export async function loadMindSpaceConfig(pool, { env = process.env } = {}) {
  const config = defaultMindSpaceConfig(env);
  try {
    const rows = await readConfigRows(pool);
    for (const row of rows) {
      if (row.key === PUBLIC_PAGE_LIMIT_KEY) {
        config.publicPageLimit = asPositiveInteger(row.value, config.publicPageLimit);
      }
    }
  } catch (error) {
    if (error?.code === 'ER_NO_SUCH_TABLE') return config;
    throw error;
  }
  return config;
}

export async function updateMindSpaceConfig(pool, patch, { env = process.env } = {}) {
  await ensureConfigTable(pool);
  const updates = [];
  if (patch?.publicPageLimit !== undefined) {
    const publicPageLimit = asPositiveInteger(patch.publicPageLimit, null);
    if (!publicPageLimit) {
      throw Object.assign(new Error('公开页面数量上限必须是大于 0 的整数'), {
        code: 'invalid_mindspace_config',
      });
    }
    updates.push([PUBLIC_PAGE_LIMIT_KEY, String(publicPageLimit), '公开页面数量上限']);
  }

  if (updates.length === 0) return loadMindSpaceConfig(pool, { env });

  const now = Date.now();
  for (const [key, value, description] of updates) {
    await pool.query(
      `INSERT INTO mindspace_config (\`key\`, value, description, updated_at)
       VALUES (?, ?, ?, ?)
       ON DUPLICATE KEY UPDATE
         value = VALUES(value),
         description = VALUES(description),
         updated_at = VALUES(updated_at)`,
      [key, value, description, now],
    );
  }
  return loadMindSpaceConfig(pool, { env });
}

export const mindspaceConfigInternals = {
  PUBLIC_PAGE_LIMIT_KEY,
};
