/**
 * Test for free plan auto-activation
 */

const SuperAdminController = require('../../../controllers/SuperAdminController');
const bcrypt = require('bcryptjs');

// Mock dependencies
jest.mock('../../../config/database', () => ({
  pool: {
    execute: jest.fn(),
    getConnection: jest.fn()
  }
}));

jest.mock('../../../config/logger', () => ({
  logger: {
    info: jest.fn(),
    error: jest.fn(),
    warn: jest.fn(),
    debug: jest.fn()
  }
}));

jest.mock('bcryptjs');

const { pool } = require('../../../config/database');

describe('SuperAdminController - Free Plan Auto-Activation', () => {
  let mockReq, mockRes, mockConnection;

  beforeEach(() => {
    jest.clearAllMocks();

    mockReq = {
      body: {},
      params: {},
      user: null
    };

    mockRes = {
      json: jest.fn().mockReturnThis(),
      status: jest.fn().mockReturnThis()
    };

    mockConnection = {
      execute: jest.fn(),
      beginTransaction: jest.fn(),
      commit: jest.fn(),
      rollback: jest.fn(),
      release: jest.fn()
    };

    pool.getConnection.mockResolvedValue(mockConnection);
  });

  describe('createTenant with free plan', () => {
    it('should create tenant with active status when plan is free', async () => {
      mockReq.body = {
        name: 'Test Company',
        email: 'test@example.com',
        phone: '1234567890',
        company_name: 'Test Company',
        plan_id: 1,
        admin_username: 'admin',
        admin_password: 'password123',
        admin_email: 'admin@example.com'
      };

      bcrypt.hash.mockResolvedValue('hashedPassword');

      // Mock database responses
      mockConnection.execute
        .mockResolvedValueOnce([[]]) // Check email doesn't exist
        .mockResolvedValueOnce([[]]) // Check subdomain doesn't exist
        .mockResolvedValueOnce([[{ 
          id: 1, 
          name: 'Free Plan',
          price: 0,
          is_free: true, // Free plan
          billing_period: 'monthly',
          max_users: 5,
          max_conversations: 100,
          max_messages_per_month: 1000,
          max_stores: 1,
          max_departments: 1,
          max_contacts: 100,
          max_devices: 1,
          max_whatsapp_instances: 1,
          max_whatsapp_cloud_accounts: 1
        }]]) // Get plan details
        .mockResolvedValueOnce([{ insertId: 1 }]) // Insert tenant
        .mockResolvedValueOnce([{ insertId: 1 }]) // Insert admin
        .mockResolvedValueOnce([{ insertId: 1 }]) // Insert bot settings
        .mockResolvedValueOnce([{ insertId: 2 }]) // Insert bot settings
        .mockResolvedValueOnce([{ insertId: 3 }]); // Insert bot settings

      await SuperAdminController.createTenant(mockReq, mockRes);

      // Verify tenant was created with 'active' status
      const tenantInsertCall = mockConnection.execute.mock.calls.find(
        call => call[0].includes('INSERT INTO tenants')
      );
      
      expect(tenantInsertCall).toBeDefined();
      expect(tenantInsertCall[1]).toContain('active'); // Status should be 'active'

      expect(mockRes.json).toHaveBeenCalledWith(
        expect.objectContaining({
          success: true,
          message: 'Tenant created successfully'
        })
      );
    });

    it('should create tenant with pending status when plan is paid', async () => {
      mockReq.body = {
        name: 'Test Company',
        email: 'test@example.com',
        phone: '1234567890',
        company_name: 'Test Company',
        plan_id: 2,
        admin_username: 'admin',
        admin_password: 'password123',
        admin_email: 'admin@example.com'
      };

      bcrypt.hash.mockResolvedValue('hashedPassword');

      // Mock database responses
      mockConnection.execute
        .mockResolvedValueOnce([[]]) // Check email doesn't exist
        .mockResolvedValueOnce([[]]) // Check subdomain doesn't exist
        .mockResolvedValueOnce([[{ 
          id: 2, 
          name: 'Pro Plan',
          price: 29.99,
          is_free: false, // Paid plan
          billing_period: 'monthly',
          max_users: 10,
          max_conversations: 1000,
          max_messages_per_month: 10000,
          max_stores: 5,
          max_departments: 5,
          max_contacts: 1000,
          max_devices: 5,
          max_whatsapp_instances: 5,
          max_whatsapp_cloud_accounts: 5
        }]]) // Get plan details
        .mockResolvedValueOnce([{ insertId: 2 }]) // Insert tenant
        .mockResolvedValueOnce([{ insertId: 2 }]) // Insert admin
        .mockResolvedValueOnce([{ insertId: 1 }]) // Insert bot settings
        .mockResolvedValueOnce([{ insertId: 2 }]) // Insert bot settings
        .mockResolvedValueOnce([{ insertId: 3 }]); // Insert bot settings

      await SuperAdminController.createTenant(mockReq, mockRes);

      // Verify tenant was created with 'pending' status
      const tenantInsertCall = mockConnection.execute.mock.calls.find(
        call => call[0].includes('INSERT INTO tenants')
      );
      
      expect(tenantInsertCall).toBeDefined();
      expect(tenantInsertCall[1]).toContain('pending'); // Status should be 'pending'

      expect(mockRes.json).toHaveBeenCalledWith(
        expect.objectContaining({
          success: true,
          message: 'Tenant created successfully'
        })
      );
    });

    it('should create tenant with active status when superadmin activates immediately', async () => {
      mockReq.user = { role: 'superadmin' };
      mockReq.body = {
        name: 'Test Company',
        email: 'test@example.com',
        phone: '1234567890',
        company_name: 'Test Company',
        plan_id: 2,
        admin_username: 'admin',
        admin_password: 'password123',
        admin_email: 'admin@example.com',
        activate_immediately: true
      };

      bcrypt.hash.mockResolvedValue('hashedPassword');

      // Mock database responses
      mockConnection.execute
        .mockResolvedValueOnce([[]]) // Check email doesn't exist
        .mockResolvedValueOnce([[]]) // Check subdomain doesn't exist
        .mockResolvedValueOnce([[{ 
          id: 2, 
          name: 'Pro Plan',
          price: 29.99,
          is_free: false,
          billing_period: 'monthly',
          max_users: 10,
          max_conversations: 1000,
          max_messages_per_month: 10000,
          max_stores: 5,
          max_departments: 5,
          max_contacts: 1000,
          max_devices: 5,
          max_whatsapp_instances: 5,
          max_whatsapp_cloud_accounts: 5
        }]]) // Get plan details
        .mockResolvedValueOnce([{ insertId: 3 }]) // Insert tenant
        .mockResolvedValueOnce([{ insertId: 3 }]) // Insert admin
        .mockResolvedValueOnce([{ insertId: 1 }]) // Insert bot settings
        .mockResolvedValueOnce([{ insertId: 2 }]) // Insert bot settings
        .mockResolvedValueOnce([{ insertId: 3 }]); // Insert bot settings

      await SuperAdminController.createTenant(mockReq, mockRes);

      // Verify tenant was created with 'active' status
      const tenantInsertCall = mockConnection.execute.mock.calls.find(
        call => call[0].includes('INSERT INTO tenants')
      );
      
      expect(tenantInsertCall).toBeDefined();
      expect(tenantInsertCall[1]).toContain('active'); // Status should be 'active'

      expect(mockRes.json).toHaveBeenCalledWith(
        expect.objectContaining({
          success: true,
          message: 'Tenant created successfully'
        })
      );
    });
  });
});
