const database = require('../config/database');
const { v4: uuidv4 } = require('uuid');

class CustomTemplate {
  constructor(data = {}) {
    this.id = data.id;
    this.type = data.type;
    this.title = data.title;
    this.description = data.description;
    this.icon = data.icon;
    this.category = data.category;
    this.gradient = data.gradient;
    this.border = data.border;
    this.text = data.text;
    this.subtext = data.subtext;
    this.complexity = data.complexity;
    this.business_rules = data.business_rules;
    this.technical_requirements = data.technical_requirements;
    this.approved = data.approved;
    this.usage_count = data.usage_count;
    this.created_by_user_session = data.created_by_user_session;
    this.created_at = data.created_at;
    this.updated_at = data.updated_at;
    this.is_custom = data.is_custom ?? false;
    // Admin approval workflow fields
    this.status = data.status || 'pending';
    this.admin_notes = data.admin_notes;
    this.admin_reviewed_at = data.admin_reviewed_at;
    this.admin_reviewed_by = data.admin_reviewed_by;
    this.canonical_template_id = data.canonical_template_id;
    this.similarity_score = data.similarity_score;
    this.user_id = data.user_id;
  }

  static async getById(id) {
    const result = await database.query('SELECT * FROM custom_templates WHERE id = $1', [id]);
    return result.rows.length ? new CustomTemplate(result.rows[0]) : null;
  }

  // Get custom template by ID with features
  static async getByIdWithFeatures(id) {
    const templateQuery = `
      SELECT * FROM custom_templates 
      WHERE id = $1
    `;
    
    const featuresQuery = `
      SELECT * FROM custom_features 
      WHERE template_id = $1 
      ORDER BY created_at DESC
    `;
    
    const [templateResult, featuresResult] = await Promise.all([
      database.query(templateQuery, [id]),
      database.query(featuresQuery, [id])
    ]);
    
    if (templateResult.rows.length === 0) {
      return null;
    }
    
    const template = new CustomTemplate(templateResult.rows[0]);
    template.features = featuresResult.rows;
    
    return template;
  }

  // Check for duplicate custom templates based on title, type, category, and user_id
  static async checkForDuplicate(templateData) {
    const normalizedTitle = (templateData.title || '').toLowerCase();
    console.log('[CustomTemplate.checkForDuplicate] Checking for duplicates:', {
      type: templateData.type,
      title: templateData.title,
      normalizedTitle,
      category: templateData.category,
      user_id: templateData.user_id
    });
    
    // Check for exact type match (globally unique)
    const typeQuery = `
      SELECT id, title, type, category, user_id FROM custom_templates 
      WHERE type = $1
    `;
    
    const typeResult = await database.query(typeQuery, [templateData.type]);
    if (typeResult.rows.length > 0) {
      console.log('[CustomTemplate.checkForDuplicate] Found duplicate by type:', typeResult.rows[0]);
      return typeResult.rows[0];
    }
    
    // Check for same title for same user (category-agnostic)
    if (templateData.user_id) {
      const titleQuery = `
        SELECT id, title, type, category, user_id FROM custom_templates 
        WHERE LOWER(title) = LOWER($1) AND user_id = $2
      `;
      
      const titleParams = [templateData.title, templateData.user_id];
      console.log('[CustomTemplate.checkForDuplicate] title check params:', titleParams);
      const titleResult = await database.query(titleQuery, titleParams);
      
      if (titleResult.rows.length > 0) {
        const row = titleResult.rows[0];
        const titleMatch = (row.title || '').toLowerCase() === normalizedTitle;
        console.log('[CustomTemplate.checkForDuplicate] Found duplicate by title+user:', {
          id: row.id,
          title: row.title,
          type: row.type,
          category: row.category,
          user_id: row.user_id,
          titleMatch
        });
        return titleResult.rows[0];
      }
    }

    // Also check if main templates already have the same title (case-insensitive)
    const mainTitleQuery = `
      SELECT id, title, type, category FROM templates 
      WHERE is_active = true AND LOWER(title) = LOWER($1)
      LIMIT 1
    `;
    const mainTitleParams = [templateData.title];
    console.log('[CustomTemplate.checkForDuplicate] main title check params:', mainTitleParams);
    const mainTitleResult = await database.query(mainTitleQuery, mainTitleParams);
    if (mainTitleResult.rows.length > 0) {
      const row = mainTitleResult.rows[0];
      const titleMatch = (row.title || '').toLowerCase() === normalizedTitle;
      console.log('[CustomTemplate.checkForDuplicate] Found duplicate title in main templates:', {
        id: row.id,
        title: row.title,
        type: row.type,
        category: row.category,
        titleMatch
      });
      return mainTitleResult.rows[0];
    }
    
    console.log('[CustomTemplate.checkForDuplicate] No duplicates found');
    return null;
  }

  // Check if template type exists in main templates table
  static async checkTypeInMainTemplates(type) {
    const query = `
      SELECT id, title, type FROM templates 
      WHERE type = $1 AND is_active = true
    `;
    
    const result = await database.query(query, [type]);
    return result.rows.length > 0 ? result.rows[0] : null;
  }

  static async create(data) {
    
    const id = uuidv4();
    console.log('[CustomTemplate.create] start - id:', id);
    const query = `
      INSERT INTO custom_templates (
        id, type, title, description, icon, category, gradient, border, text, subtext,
        complexity, business_rules, technical_requirements, approved, usage_count, 
        created_by_user_session, status, admin_notes, admin_reviewed_at, 
        admin_reviewed_by, canonical_template_id, similarity_score, is_custom, user_id
      ) VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20,$21,$22,$23,$24)
      RETURNING *
    `;
    const values = [
      id,
      data.type,
      data.title,
      data.description || null,
      data.icon || null,
      data.category,
      data.gradient || null,
      data.border || null,
      data.text || null,
      data.subtext || null,
      data.complexity,
      data.business_rules || null,
      data.technical_requirements || null,
      data.approved ?? false,
      data.usage_count ?? 1,
      data.created_by_user_session || null,
      data.status || 'pending',
      data.admin_notes || null,
      data.admin_reviewed_at || null,
      data.admin_reviewed_by || null,
      data.canonical_template_id || null,
      data.similarity_score || null,
      data.is_custom ?? false,
      data.user_id || null,
    ];
    console.log('[CustomTemplate.create] values prepared (truncated):', {
      id: values[0],
      type: values[1],
      title: values[2],
      is_custom: values[22],
      user_id: values[23]
    });
    const result = await database.query(query, values);
    console.log('[CustomTemplate.create] insert done - row id:', result.rows[0]?.id, 'user_id:', result.rows[0]?.user_id);
    return new CustomTemplate(result.rows[0]);
  }

  static async update(id, updates) {
    const fields = [];
    const values = [];
    let idx = 1;
    const allowed = [
      'title', 'description', 'icon', 'category', 'gradient', 'border', 'text', 'subtext',
      'complexity', 'business_rules', 'technical_requirements', 'approved', 'usage_count',
      'status', 'admin_notes', 'admin_reviewed_at', 'admin_reviewed_by', 
      'canonical_template_id', 'similarity_score', 'user_id'
    ];
    for (const k of allowed) {
      if (updates[k] !== undefined) {
        fields.push(`${k} = $${idx++}`);
        values.push(updates[k]);
      }
    }
    if (fields.length === 0) return await CustomTemplate.getById(id);
    const query = `UPDATE custom_templates SET ${fields.join(', ')}, updated_at = NOW() WHERE id = $${idx} RETURNING *`;
    values.push(id);
    const result = await database.query(query, values);
    return result.rows.length ? new CustomTemplate(result.rows[0]) : null;
  }

  static async delete(id) {
    const result = await database.query('DELETE FROM custom_templates WHERE id = $1', [id]);
    return result.rowCount > 0;
  }

  // Admin workflow methods
  static async getPendingTemplates(limit = 50, offset = 0) {
    const query = `
      SELECT * FROM custom_templates
      WHERE status = 'pending'
      ORDER BY created_at ASC
      LIMIT $1 OFFSET $2
    `;
    const result = await database.query(query, [limit, offset]);
    return result.rows.map(r => new CustomTemplate(r));
  }

  static async getTemplatesByStatus(status, limit = 50, offset = 0) {
    const query = `
      SELECT * FROM custom_templates
      WHERE status = $1
      ORDER BY created_at DESC
      LIMIT $2 OFFSET $3
    `;
    const result = await database.query(query, [status, limit, offset]);
    return result.rows.map(r => new CustomTemplate(r));
  }

  // Get custom templates created by a specific user session
  static async getByCreatorSession(sessionKey, limit = 100, offset = 0, status = null) {
    if (!sessionKey) return [];
    let query = `
      SELECT * FROM custom_templates
      WHERE created_by_user_session = $1
    `;
    const values = [sessionKey];
    if (status) {
      query += ` AND status = $2`;
      values.push(status);
    }
    query += ` ORDER BY created_at DESC LIMIT ${status ? '$3' : '$2'} OFFSET ${status ? '$4' : '$3'}`;
    values.push(limit, offset);
    const result = await database.query(query, values);
    return result.rows.map(r => new CustomTemplate(r));
  }

  static async getTemplateStats() {
    const query = `
      SELECT 
        status,
        COUNT(*) as count
      FROM custom_templates
      GROUP BY status
    `;
    const result = await database.query(query);
    return result.rows;
  }

  // Get custom templates by authenticated user id
  static async getByUserId(userId, limit = 100, offset = 0, status = null) {
    if (!userId) return [];
    let query = `
      SELECT * FROM custom_templates
      WHERE user_id = $1
    `;
    const values = [userId];
    if (status) {
      query += ` AND status = $2`;
      values.push(status);
    }
    query += ` ORDER BY created_at DESC LIMIT ${status ? '$3' : '$2'} OFFSET ${status ? '$4' : '$3'}`;
    values.push(limit, offset);
    const result = await database.query(query, values);
    return result.rows.map(r => new CustomTemplate(r));
  }

  static async reviewTemplate(id, reviewData) {
    const { status, admin_notes, canonical_template_id, admin_reviewed_by } = reviewData;
    
    const updates = {
      status,
      admin_notes,
      admin_reviewed_at: new Date(),
      admin_reviewed_by
    };

    // Maintain the legacy boolean flag alongside the status for easier filtering
    if (status === 'approved') {
      updates.approved = true;
    } else if (status === 'rejected' || status === 'duplicate') {
      updates.approved = false;
    }

    if (canonical_template_id) {
      updates.canonical_template_id = canonical_template_id;
    }

    return await CustomTemplate.update(id, updates);
  }

  // Get all custom templates
  static async getAll(limit = 100, offset = 0) {
    const query = `
      SELECT * FROM custom_templates
      ORDER BY created_at DESC
      LIMIT $1 OFFSET $2
    `;
    const result = await database.query(query, [limit, offset]);
    return result.rows.map(r => new CustomTemplate(r));
  }

  // Search custom templates
  static async search(searchTerm, limit = 20) {
    const query = `
      SELECT * FROM custom_templates
      WHERE (title ILIKE $1 OR description ILIKE $1 OR category ILIKE $1)
      ORDER BY usage_count DESC, created_at DESC
      LIMIT $2
    `;
    const result = await database.query(query, [`%${searchTerm}%`, limit]);
    return result.rows.map(r => new CustomTemplate(r));
  }
  // Get statistics for admin dashboard
  static async getStats() {
    const query = `
      SELECT 
        status,
        COUNT(*) as count
      FROM custom_templates 
      GROUP BY status
    `;
    
    const result = await database.query(query);
    return result.rows.map(row => ({
      status: row.status,
      count: parseInt(row.count) || 0
    }));
  }

  // Alias for getAll method to match admin route expectations
  static async getAllTemplates(limit = 50, offset = 0) {
    return await CustomTemplate.getAll(limit, offset);
  }
}

module.exports = CustomTemplate;
