/**
 * Test Data Manager
 * Centralized test data management for HVAC testing framework
 */

const fs = require('fs').promises;
const path = require('path');

class TestDataManager {
    constructor(environment = 'staging') {
        this.environment = environment;
        this.dataCache = new Map();
        this.fixturesPath = path.join(__dirname, 'fixtures');
        this.accounts = null;
        this.testData = null;
    }

    /**
     * Initialize test data manager
     * @returns {Promise<void>}
     */
    async initialize() {
        await this.loadTestAccounts();
        await this.loadTestData();
        await this.loadFixtures();
    }

    /**
     * Load test accounts for different environments
     * @returns {Promise<void>}
     */
    async loadTestAccounts() {
        this.accounts = {
            staging: {
                masterTrainer: {
                    username: 'test_master',
                    password: 'TestMaster123!',
                    email: 'test_master@example.com',
                    role: 'master_trainer',
                    displayName: 'Test Master Trainer',
                    capabilities: ['manage_events', 'manage_trainers', 'view_announcements']
                },
                alternateMasterTrainer: {
                    username: 'JoeMedosch@gmail.com',
                    password: 'JoeTrainer2025@',
                    email: 'JoeMedosch@gmail.com',
                    role: 'master_trainer',
                    displayName: 'Joe Medosch',
                    capabilities: ['manage_events', 'manage_trainers', 'view_announcements']
                },
                trainer: {
                    username: 'test_trainer',
                    password: 'TestTrainer123!',
                    email: 'test_trainer@example.com',
                    role: 'hvac_trainer',
                    displayName: 'Test Trainer',
                    capabilities: ['create_events', 'manage_profile', 'view_leads']
                },
                admin: {
                    username: process.env.STAGING_ADMIN_USER || 'admin',
                    password: process.env.STAGING_ADMIN_PASSWORD || 'admin_password',
                    email: 'admin@example.com',
                    role: 'administrator',
                    displayName: 'Site Administrator',
                    capabilities: ['manage_options', 'manage_users', 'manage_plugins']
                }
            },
            production: {
                masterTrainer: {
                    username: process.env.PROD_MASTER_USERNAME,
                    password: process.env.PROD_MASTER_PASSWORD,
                    email: process.env.PROD_MASTER_EMAIL,
                    role: 'master_trainer',
                    displayName: 'Production Master Trainer',
                    capabilities: ['manage_events', 'manage_trainers', 'view_announcements']
                },
                trainer: {
                    username: process.env.PROD_TRAINER_USERNAME,
                    password: process.env.PROD_TRAINER_PASSWORD,
                    email: process.env.PROD_TRAINER_EMAIL,
                    role: 'hvac_trainer',
                    displayName: 'Production Trainer',
                    capabilities: ['create_events', 'manage_profile', 'view_leads']
                }
            },
            local: {
                masterTrainer: {
                    username: 'master_local',
                    password: 'MasterLocal123!',
                    email: 'master@localhost.dev',
                    role: 'master_trainer',
                    displayName: 'Local Master Trainer',
                    capabilities: ['manage_events', 'manage_trainers', 'view_announcements']
                },
                trainer: {
                    username: 'trainer_local',
                    password: 'TrainerLocal123!',
                    email: 'trainer@localhost.dev',
                    role: 'hvac_trainer',
                    displayName: 'Local Trainer',
                    capabilities: ['create_events', 'manage_profile', 'view_leads']
                },
                admin: {
                    username: 'admin',
                    password: 'admin123',
                    email: 'admin@localhost.dev',
                    role: 'administrator',
                    displayName: 'Local Admin',
                    capabilities: ['manage_options', 'manage_users', 'manage_plugins']
                }
            }
        };
    }

    /**
     * Load test data for different scenarios
     * @returns {Promise<void>}
     */
    async loadTestData() {
        this.testData = {
            events: {
                basicEvent: {
                    title: 'Test HVAC Training Event',
                    description: 'This is a test event for HVAC training purposes.',
                    startDate: this.getFutureDate(7), // 7 days from now
                    endDate: this.getFutureDate(8),   // 8 days from now
                    startTime: '09:00:00',
                    endTime: '17:00:00',
                    location: 'Test Training Center',
                    address: '123 Test Street, Test City, TS 12345',
                    capacity: 20,
                    status: 'published',
                    eventType: 'training',
                    categories: ['hvac', 'training', 'test']
                },
                fullEvent: {
                    title: 'Comprehensive HVAC Certification Course',
                    description: 'Complete HVAC certification training with hands-on experience.',
                    startDate: this.getFutureDate(14),
                    endDate: this.getFutureDate(16),
                    startTime: '08:30:00',
                    endTime: '18:00:00',
                    location: 'Advanced Training Facility',
                    address: '456 Training Avenue, Education City, ED 54321',
                    capacity: 15,
                    price: 299.99,
                    instructorNotes: 'Bring work clothes and safety equipment',
                    prerequisites: 'Basic electrical knowledge required',
                    materials: 'All materials provided',
                    certification: 'EPA 608 Certification',
                    status: 'published',
                    eventType: 'certification',
                    categories: ['hvac', 'certification', 'advanced']
                },
                pastEvent: {
                    title: 'Past HVAC Workshop',
                    description: 'This event has already occurred.',
                    startDate: this.getPastDate(30),
                    endDate: this.getPastDate(30),
                    startTime: '10:00:00',
                    endTime: '16:00:00',
                    location: 'Past Event Venue',
                    address: '789 Past Street, History City, HI 98765',
                    capacity: 12,
                    status: 'completed',
                    eventType: 'workshop'
                }
            },
            venues: {
                basicVenue: {
                    name: 'Test Training Center',
                    address: '123 Test Street',
                    city: 'Test City',
                    state: 'TS',
                    zipCode: '12345',
                    phone: '555-TEST-001',
                    email: 'contact@testcenter.com',
                    capacity: 25,
                    facilities: ['parking', 'wifi', 'projector'],
                    notes: 'Accessible venue with modern facilities'
                },
                advancedVenue: {
                    name: 'Advanced Training Facility',
                    address: '456 Training Avenue',
                    city: 'Education City',
                    state: 'ED',
                    zipCode: '54321',
                    phone: '555-ADV-002',
                    email: 'info@advancedtraining.com',
                    website: 'https://advancedtraining.com',
                    capacity: 30,
                    facilities: ['parking', 'wifi', 'projector', 'lab_equipment', 'tools'],
                    notes: 'Full HVAC lab with latest equipment'
                }
            },
            organizers: {
                testOrganizer: {
                    name: 'Test Training Organization',
                    contactName: 'Jane Organizer',
                    email: 'jane@testorg.com',
                    phone: '555-ORG-001',
                    website: 'https://testorg.com',
                    address: '123 Organization Street, Org City, OG 12345',
                    notes: 'Primary test organizer for training events'
                },
                corporateOrganizer: {
                    name: 'Corporate HVAC Training',
                    contactName: 'John Corporate',
                    email: 'john@corporate-hvac.com',
                    phone: '555-CORP-002',
                    website: 'https://corporate-hvac.com',
                    address: '789 Corporate Plaza, Business City, BC 67890',
                    taxId: '12-3456789',
                    notes: 'Large scale training provider'
                }
            },
            announcements: {
                generalAnnouncement: {
                    title: 'Test General Announcement',
                    content: 'This is a test announcement for general information.',
                    priority: 'normal',
                    targetAudience: 'all',
                    startDate: this.getCurrentDate(),
                    endDate: this.getFutureDate(30),
                    status: 'published',
                    author: 'Test Master Trainer'
                },
                urgentAnnouncement: {
                    title: 'Urgent: Test Emergency Announcement',
                    content: 'This is an urgent test announcement that requires immediate attention.',
                    priority: 'high',
                    targetAudience: 'trainers',
                    startDate: this.getCurrentDate(),
                    endDate: this.getFutureDate(7),
                    status: 'published',
                    urgent: true,
                    emailNotification: true
                }
            },
            forms: {
                eventRegistration: {
                    firstName: 'Test',
                    lastName: 'Participant',
                    email: 'test.participant@example.com',
                    phone: '555-PART-001',
                    company: 'Test Company LLC',
                    experience: 'beginner',
                    specialRequirements: 'None',
                    emergencyContact: 'Emergency Contact',
                    emergencyPhone: '555-EMRG-001'
                },
                trainerProfile: {
                    firstName: 'Test',
                    lastName: 'Trainer',
                    email: 'test.trainer@example.com',
                    phone: '555-TRAIN-001',
                    company: 'HVAC Training Pro',
                    experience: '5-10 years',
                    certifications: ['EPA 608', 'NATE Certified'],
                    specialties: ['Installation', 'Maintenance', 'Troubleshooting'],
                    bio: 'Experienced HVAC professional with focus on training.',
                    website: 'https://hvactrainingpro.com',
                    linkedIn: 'https://linkedin.com/in/testtrainer'
                }
            }
        };
    }

    /**
     * Load fixtures from JSON files
     * @returns {Promise<void>}
     */
    async loadFixtures() {
        try {
            // Ensure fixtures directory exists
            await fs.mkdir(this.fixturesPath, { recursive: true });
            
            // Load existing fixtures or create defaults
            await this.loadOrCreateFixture('users.json', this.accounts[this.environment] || this.accounts.staging);
            await this.loadOrCreateFixture('events.json', this.testData.events);
            await this.loadOrCreateFixture('venues.json', this.testData.venues);
            await this.loadOrCreateFixture('organizers.json', this.testData.organizers);
            await this.loadOrCreateFixture('announcements.json', this.testData.announcements);
            
        } catch (error) {
            console.warn(`Failed to load fixtures: ${error.message}`);
        }
    }

    /**
     * Load fixture file or create with default data
     * @param {string} filename - Fixture filename
     * @param {Object} defaultData - Default data if file doesn't exist
     * @returns {Promise<Object>}
     */
    async loadOrCreateFixture(filename, defaultData) {
        const filePath = path.join(this.fixturesPath, filename);
        
        try {
            const content = await fs.readFile(filePath, 'utf8');
            const data = JSON.parse(content);
            this.dataCache.set(filename, data);
            return data;
        } catch (error) {
            // File doesn't exist, create with default data
            await fs.writeFile(filePath, JSON.stringify(defaultData, null, 2));
            this.dataCache.set(filename, defaultData);
            return defaultData;
        }
    }

    /**
     * Get test account by role
     * @param {string} role - User role (masterTrainer, trainer, admin, etc.)
     * @returns {Object|null}
     */
    getTestAccount(role) {
        const envAccounts = this.accounts[this.environment] || this.accounts.staging;
        return envAccounts[role] || null;
    }

    /**
     * Get all test accounts for current environment
     * @returns {Object}
     */
    getAllTestAccounts() {
        return this.accounts[this.environment] || this.accounts.staging;
    }

    /**
     * Get test data by category and type
     * @param {string} category - Data category (events, venues, etc.)
     * @param {string} type - Data type (basicEvent, fullEvent, etc.)
     * @returns {Object|null}
     */
    getTestData(category, type) {
        if (!this.testData[category]) return null;
        return this.testData[category][type] || null;
    }

    /**
     * Get all test data for a category
     * @param {string} category - Data category
     * @returns {Object|null}
     */
    getTestDataCategory(category) {
        return this.testData[category] || null;
    }

    /**
     * Generate unique test data
     * @param {string} category - Data category
     * @param {string} type - Data type
     * @param {Object} overrides - Properties to override
     * @returns {Object}
     */
    generateUniqueTestData(category, type, overrides = {}) {
        const baseData = this.getTestData(category, type);
        if (!baseData) return null;

        const uniqueData = { ...baseData };
        const timestamp = Date.now();
        
        // Add unique identifiers
        if (uniqueData.title) {
            uniqueData.title = `${uniqueData.title} - ${timestamp}`;
        }
        if (uniqueData.name) {
            uniqueData.name = `${uniqueData.name} - ${timestamp}`;
        }
        if (uniqueData.email) {
            uniqueData.email = uniqueData.email.replace('@', `+${timestamp}@`);
        }
        
        // Apply overrides
        Object.assign(uniqueData, overrides);
        
        return uniqueData;
    }

    /**
     * Create test event data with random variations
     * @param {Object} overrides - Properties to override
     * @returns {Object}
     */
    createRandomEventData(overrides = {}) {
        const eventTypes = ['training', 'workshop', 'certification', 'seminar'];
        const locations = ['Training Center A', 'Workshop Venue B', 'Conference Hall C'];
        const cities = ['Training City', 'Workshop Town', 'Education Village'];
        
        const randomEvent = {
            title: `${this.getRandomElement(['Advanced', 'Basic', 'Intermediate'])} HVAC ${this.getRandomElement(['Training', 'Workshop', 'Course'])}`,
            description: 'Comprehensive HVAC training with hands-on experience.',
            startDate: this.getFutureDate(Math.floor(Math.random() * 30) + 1),
            endDate: this.getFutureDate(Math.floor(Math.random() * 30) + 2),
            startTime: '09:00:00',
            endTime: '17:00:00',
            location: this.getRandomElement(locations),
            address: `${Math.floor(Math.random() * 999) + 100} ${this.getRandomElement(['Main', 'Training', 'Education'])} Street, ${this.getRandomElement(cities)}, TC 12345`,
            capacity: Math.floor(Math.random() * 30) + 10,
            eventType: this.getRandomElement(eventTypes),
            status: 'published'
        };
        
        return { ...randomEvent, ...overrides };
    }

    /**
     * Get protected URLs for security testing
     * @returns {string[]}
     */
    getProtectedUrls() {
        return [
            '/trainer/dashboard/',
            '/trainer/venue/list/',
            '/trainer/venue/manage/', 
            '/trainer/organizer/manage/',
            '/trainer/profile/training-leads/',
            '/master-trainer/master-dashboard/',
            '/master-trainer/events/',
            '/master-trainer/google-sheets/',
            '/master-trainer/announcements/',
            '/master-trainer/pending-approvals/',
            '/master-trainer/trainers/',
            '/master-trainer/communication-templates/'
        ];
    }

    /**
     * Get role-based access test scenarios
     * @returns {Array}
     */
    getRoleAccessTestScenarios() {
        const masterTrainer = this.getTestAccount('masterTrainer');
        const trainer = this.getTestAccount('trainer');
        
        return [
            // Master trainer should have access to master trainer pages
            { user: masterTrainer, url: '/master-trainer/master-dashboard/', expectedAccess: true },
            { user: masterTrainer, url: '/master-trainer/events/', expectedAccess: true },
            { user: masterTrainer, url: '/master-trainer/trainers/', expectedAccess: true },
            
            // Regular trainer should NOT have access to master trainer pages
            { user: trainer, url: '/master-trainer/master-dashboard/', expectedAccess: false },
            { user: trainer, url: '/master-trainer/events/', expectedAccess: false },
            { user: trainer, url: '/master-trainer/trainers/', expectedAccess: false },
            
            // Regular trainer should have access to trainer pages
            { user: trainer, url: '/trainer/dashboard/', expectedAccess: true },
            { user: trainer, url: '/trainer/venue/manage/', expectedAccess: true },
            { user: trainer, url: '/trainer/organizer/manage/', expectedAccess: true }
        ];
    }

    /**
     * Get current date in YYYY-MM-DD format
     * @returns {string}
     */
    getCurrentDate() {
        return new Date().toISOString().split('T')[0];
    }

    /**
     * Get future date in YYYY-MM-DD format
     * @param {number} daysFromNow - Days in the future
     * @returns {string}
     */
    getFutureDate(daysFromNow) {
        const date = new Date();
        date.setDate(date.getDate() + daysFromNow);
        return date.toISOString().split('T')[0];
    }

    /**
     * Get past date in YYYY-MM-DD format
     * @param {number} daysAgo - Days in the past
     * @returns {string}
     */
    getPastDate(daysAgo) {
        const date = new Date();
        date.setDate(date.getDate() - daysAgo);
        return date.toISOString().split('T')[0];
    }

    /**
     * Get random element from array
     * @param {Array} array - Array to select from
     * @returns {*}
     * @private
     */
    getRandomElement(array) {
        return array[Math.floor(Math.random() * array.length)];
    }

    /**
     * Save test data to fixture file
     * @param {string} filename - Fixture filename
     * @param {Object} data - Data to save
     * @returns {Promise<void>}
     */
    async saveFixture(filename, data) {
        const filePath = path.join(this.fixturesPath, filename);
        await fs.writeFile(filePath, JSON.stringify(data, null, 2));
        this.dataCache.set(filename, data);
    }

    /**
     * Clear all cached test data
     * @returns {void}
     */
    clearCache() {
        this.dataCache.clear();
    }

    /**
     * Get fixture data
     * @param {string} filename - Fixture filename
     * @returns {Object|null}
     */
    getFixture(filename) {
        return this.dataCache.get(filename) || null;
    }
}

// Singleton instance
let testDataManager = null;

/**
 * Get singleton TestDataManager instance
 * @param {string} environment - Environment name
 * @returns {TestDataManager}
 */
function getTestDataManager(environment = 'staging') {
    if (!testDataManager || testDataManager.environment !== environment) {
        testDataManager = new TestDataManager(environment);
    }
    return testDataManager;
}

module.exports = { TestDataManager, getTestDataManager };