const db = require('../../database/database');
const { logger } = require('../../middleware/logger');

exports.list = async () => {
  const [rows] = await db.query('SELECT * FROM affiliates ORDER BY created_at DESC');
  return rows.map(r => ({
    id: r.id,
    name: r.name,
    description: r.description,
    url: r.url,
    object_storage_id: r.object_storage_id,
    original_filename: r.original_filename,
    category: r.category,
    is_active: !!r.is_active,
    commission_rate: r.commission_rate,
    created_at: r.created_at,
    updated_at: r.updated_at
  }));
};

exports.get = async (id) => {
  const [rows] = await db.query('SELECT * FROM affiliates WHERE id = ?', [id]);
  if (!rows[0]) return null;
  const r = rows[0];
  return {
    id: r.id,
    name: r.name,
    description: r.description,
    url: r.url,
    object_storage_id: r.object_storage_id,
    original_filename: r.original_filename,
    category: r.category,
    is_active: !!r.is_active,
    commission_rate: r.commission_rate,
    created_at: r.created_at,
    updated_at: r.updated_at
  };
};

exports.create = async ({ name, description, url, category, is_active, commission_rate, object_storage_id, original_filename }) => {
  // Validation
  if (!name || name.trim() === '') {
    const e = new Error('Affiliate name is required');
    e.code = 'VALIDATION_ERROR';
    throw e;
  }
  if (!url || url.trim() === '') {
    const e = new Error('Affiliate URL is required');
    e.code = 'VALIDATION_ERROR';
    throw e;
  }
  if (!category || category.trim() === '') {
    const e = new Error('Affiliate category is required');
    e.code = 'VALIDATION_ERROR';
    throw e;
  }

  // Validate URL format
  try {
    new URL(url);
  } catch (err) {
    const e = new Error('Invalid URL format');
    e.code = 'VALIDATION_ERROR';
    throw e;
  }

  const [result] = await db.query(
    `INSERT INTO affiliates (name, description, url, category, is_active, commission_rate, object_storage_id, original_filename)
     VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
    [
      name.trim(),
      description ? description.trim() : null,
      url.trim(),
      category.trim(),
      is_active !== undefined ? is_active : true,
      commission_rate || null,
      object_storage_id || null,
      original_filename || null
    ]
  );
  logger.info('[AffiliateService.create] created', { id: result.insertId });
  return await exports.get(result.insertId);
};

exports.update = async (id, { name, description, url, category, is_active, commission_rate, object_storage_id, original_filename }) => {
  const updates = [];
  const values = [];

  if (name !== undefined) {
    updates.push('name = ?');
    values.push(name.trim());
  }
  if (description !== undefined) {
    updates.push('description = ?');
    values.push(description ? description.trim() : null);
  }
  if (url !== undefined) {
    // Validate URL format
    try {
      new URL(url);
    } catch (err) {
      const e = new Error('Invalid URL format');
      e.code = 'VALIDATION_ERROR';
      throw e;
    }
    updates.push('url = ?');
    values.push(url.trim());
  }
  if (category !== undefined) {
    updates.push('category = ?');
    values.push(category.trim());
  }
  if (is_active !== undefined) {
    updates.push('is_active = ?');
    values.push(is_active);
  }
  if (commission_rate !== undefined) {
    updates.push('commission_rate = ?');
    values.push(commission_rate);
  }
  if (object_storage_id !== undefined) {
    updates.push('object_storage_id = ?');
    values.push(object_storage_id);
  }
  if (original_filename !== undefined) {
    updates.push('original_filename = ?');
    values.push(original_filename);
  }

  if (updates.length === 0) {
    logger.warn('[AffiliateService.update] no fields to update', { id });
    return await exports.get(id);
  }

  updates.push('updated_at = NOW()');
  values.push(id);

  await db.query(`UPDATE affiliates SET ${updates.join(', ')} WHERE id = ?`, values);
  logger.info('[AffiliateService.update] updated', { id });
  return await exports.get(id);
};

exports.updateStatus = async (id, is_active) => {
  await db.query('UPDATE affiliates SET is_active = ?, updated_at = NOW() WHERE id = ?', [is_active, id]);
  logger.info('[AffiliateService.updateStatus] updated', { id, is_active });
  return await exports.get(id);
};

exports.delete = async (id) => {
  await db.query('DELETE FROM affiliates WHERE id = ?', [id]);
  logger.info('[AffiliateService.delete] deleted', { id });
};
