const Affiliate = require('../../models/Affiliate');
const { logger } = require('../../middleware/logger');

class AffiliateRepository {
  constructor(db) {
    this.db = db;
  }

  /**
   * Get all affiliates
   */
  async getAll() {
    const query = `
      SELECT * FROM affiliates
      ORDER BY created_at DESC
    `;
    
    try {
      const [rows] = await this.db.query(query);
      return rows.map(row => Affiliate.fromDbRow(row));
    } catch (error) {
      logger.error('[AffiliateRepository] Error getting all affiliates:', error);
      throw error;
    }
  }

  /**
   * Get affiliate by ID
   */
  async getById(id) {
    const query = `SELECT * FROM affiliates WHERE id = ?`;
    
    try {
      const [rows] = await this.db.query(query, [id]);
      return rows.length > 0 ? Affiliate.fromDbRow(rows[0]) : null;
    } catch (error) {
      logger.error(`[AffiliateRepository] Error getting affiliate by ID ${id}:`, error);
      throw error;
    }
  }

  /**
   * Get active affiliates only
   */
  async getActive() {
    const query = `
      SELECT * FROM affiliates
      WHERE is_active = 1
      ORDER BY created_at DESC
    `;
    
    try {
      const [rows] = await this.db.query(query);
      return rows.map(row => Affiliate.fromDbRow(row));
    } catch (error) {
      logger.error('[AffiliateRepository] Error getting active affiliates:', error);
      throw error;
    }
  }

  /**
   * Get affiliates by category
   */
  async getByCategory(category) {
    const query = `
      SELECT * FROM affiliates
      WHERE category = ?
      ORDER BY created_at DESC
    `;
    
    try {
      const [rows] = await this.db.query(query, [category]);
      return rows.map(row => Affiliate.fromDbRow(row));
    } catch (error) {
      logger.error(`[AffiliateRepository] Error getting affiliates by category ${category}:`, error);
      throw error;
    }
  }

  /**
   * Create new affiliate
   */
  async create({ name, description, url, object_storage_id, original_filename, category, is_active, commission_rate }) {
    const query = `
      INSERT INTO affiliates (name, description, url, object_storage_id, original_filename, category, is_active, commission_rate)
      VALUES (?, ?, ?, ?, ?, ?, ?, ?)
    `;
    
    try {
      const [result] = await this.db.query(query, [
        name,
        description || null,
        url,
        object_storage_id || null,
        original_filename || null,
        category,
        is_active !== undefined ? is_active : true,
        commission_rate || null
      ]);
      
      logger.info(`[AffiliateRepository] Created affiliate with ID: ${result.insertId}`);
      return await this.getById(result.insertId);
    } catch (error) {
      logger.error('[AffiliateRepository] Error creating affiliate:', error);
      throw error;
    }
  }

  /**
   * Update affiliate
   */
  async update(id, { name, description, url, object_storage_id, original_filename, category, is_active, commission_rate }) {
    const updates = [];
    const values = [];

    if (name !== undefined) {
      updates.push('name = ?');
      values.push(name);
    }
    if (description !== undefined) {
      updates.push('description = ?');
      values.push(description);
    }
    if (url !== undefined) {
      updates.push('url = ?');
      values.push(url);
    }
    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 (category !== undefined) {
      updates.push('category = ?');
      values.push(category);
    }
    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 (updates.length === 0) {
      logger.warn(`[AffiliateRepository] No fields to update for affiliate ID ${id}`);
      return await this.getById(id);
    }

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

    const query = `UPDATE affiliates SET ${updates.join(', ')} WHERE id = ?`;
    
    try {
      await this.db.query(query, values);
      logger.info(`[AffiliateRepository] Updated affiliate ID: ${id}`);
      return await this.getById(id);
    } catch (error) {
      logger.error(`[AffiliateRepository] Error updating affiliate ID ${id}:`, error);
      throw error;
    }
  }

  /**
   * Delete affiliate
   */
  async delete(id) {
    const query = `DELETE FROM affiliates WHERE id = ?`;
    
    try {
      const [result] = await this.db.query(query, [id]);
      logger.info(`[AffiliateRepository] Deleted affiliate ID: ${id}`);
      return result.affectedRows > 0;
    } catch (error) {
      logger.error(`[AffiliateRepository] Error deleting affiliate ID ${id}:`, error);
      throw error;
    }
  }

  /**
   * Update affiliate status (active/inactive)
   */
  async updateStatus(id, is_active) {
    const query = `UPDATE affiliates SET is_active = ?, updated_at = NOW() WHERE id = ?`;
    
    try {
      await this.db.query(query, [is_active, id]);
      logger.info(`[AffiliateRepository] Updated status for affiliate ID ${id} to ${is_active}`);
      return await this.getById(id);
    } catch (error) {
      logger.error(`[AffiliateRepository] Error updating status for affiliate ID ${id}:`, error);
      throw error;
    }
  }
}

module.exports = AffiliateRepository;
