import { db } from '../database.js'
import { escapeLike } from '../../utils/escapeLike.js'

function deserialize(row) {
  return {
    ...row,
    asymmetric: Boolean(row.asymmetric),
    alternate: Boolean(row.alternate),
    image_urls: JSON.parse(row.image_urls || '[]'),
    video_urls: JSON.parse(row.video_urls || '[]'),
  }
}

export const exerciseRepository = {
  async create(exercise) {
    const id = crypto.randomUUID()
    await db.run(
      `INSERT INTO exercise (id, title, description, asymmetric, alternate,
        image_urls, video_urls, default_reps, default_weight, created_by)
       VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
      [
        id,
        exercise.title,
        exercise.description || '',
        exercise.asymmetric ? 1 : 0,
        exercise.alternate ? 1 : 0,
        JSON.stringify(exercise.image_urls || []),
        JSON.stringify(exercise.video_urls || []),
        exercise.default_reps || 0,
        exercise.default_weight || 0,
        exercise.created_by,
      ],
    )
    return id
  },

  async getById(id) {
    const row = await db.selectOne('SELECT * FROM exercise WHERE id = ?', [id])
    return row ? deserialize(row) : null
  },

  async getAll() {
    const rows = await db.selectAll('SELECT * FROM exercise ORDER BY title')
    return rows.map(deserialize)
  },

  async update(id, data) {
    return db.run(
      `UPDATE exercise SET title = ?, description = ?, asymmetric = ?,
        alternate = ?, image_urls = ?, video_urls = ?,
        default_reps = ?, default_weight = ?
       WHERE id = ?`,
      [
        data.title,
        data.description || '',
        data.asymmetric ? 1 : 0,
        data.alternate ? 1 : 0,
        JSON.stringify(data.image_urls || []),
        JSON.stringify(data.video_urls || []),
        data.default_reps || 0,
        data.default_weight || 0,
        id,
      ],
    )
  },

  /**
   * Insert an exercise with a specific ID (for import scenarios).
   */
  async createWithId(id, exercise) {
    await db.run(
      `INSERT INTO exercise (id, title, description, asymmetric, alternate,
        image_urls, video_urls, default_reps, default_weight, created_by)
       VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
      [
        id,
        exercise.title,
        exercise.description || '',
        exercise.asymmetric ? 1 : 0,
        exercise.alternate ? 1 : 0,
        JSON.stringify(exercise.image_urls || []),
        JSON.stringify(exercise.video_urls || []),
        exercise.default_reps || 0,
        exercise.default_weight || 0,
        exercise.created_by,
      ],
    )
    return id
  },

  /**
   * Replace (update) all fields including created_by (for import overwrite).
   */
  async replaceAll(id, data) {
    return db.run(
      `UPDATE exercise SET title = ?, description = ?, asymmetric = ?,
        alternate = ?, image_urls = ?, video_urls = ?,
        default_reps = ?, default_weight = ?, created_by = ?
       WHERE id = ?`,
      [
        data.title,
        data.description || '',
        data.asymmetric ? 1 : 0,
        data.alternate ? 1 : 0,
        JSON.stringify(data.image_urls || []),
        JSON.stringify(data.video_urls || []),
        data.default_reps || 0,
        data.default_weight || 0,
        data.created_by,
        id,
      ],
    )
  },

  async delete(id) {
    // session_item.item_id is polymorphic (no FK), so exercise entries in
    // sessions must be removed explicitly or they'd linger as orphans
    return db.batch([
      {
        sql: "DELETE FROM session_item WHERE item_id = ? AND item_type = 'exercise'",
        params: [id],
      },
      { sql: 'DELETE FROM exercise WHERE id = ?', params: [id] },
    ])
  },

  async search(query) {
    const rows = await db.selectAll(
      "SELECT * FROM exercise WHERE title LIKE ? ESCAPE '\\' ORDER BY title",
      [`%${escapeLike(query)}%`],
    )
    return rows.map(deserialize)
  },
}
