/**
 * Public Pages Object Models
 * 
 * Page objects for public-facing pages including authentication flows
 * and public access pages for comprehensive E2E testing.
 * 
 * @package HVAC_Community_Events
 * @version 2.0.0
 * @created 2025-08-27
 */

const BasePage = require('../../framework/base/BasePage');

/**
 * Training Login Page Object
 */
class TrainingLoginPage extends BasePage {
    constructor() {
        super();
        this.url = '/training-login/';
        this.selectors = {
            loginForm: 'form#loginform, form.login-form, form[name="loginform"]',
            usernameField: '#user_login, input[name="log"], input[name="username"]',
            passwordField: '#user_pass, input[name="pwd"], input[name="password"]',
            submitButton: '#wp-submit, input[type="submit"], button[type="submit"]',
            errorMessage: '.login_error, .error, .notice-error, .warning',
            forgotPasswordLink: 'a[href*="lostpassword"], a[href*="forgot"], a:has-text("Forgot")',
            rememberMe: '#rememberme, input[name="rememberme"]'
        };
    }

    async waitForPageReady() {
        await this.waitForElement(this.selectors.loginForm, 30000);
    }

    async login(username, password) {
        await this.fillField(this.selectors.usernameField, username);
        await this.fillField(this.selectors.passwordField, password);
        await this.clickElement(this.selectors.submitButton);
        
        // Wait for redirect or error
        await this.page.waitForTimeout(3000);
    }

    async getErrorMessage() {
        try {
            return await this.getElementText(this.selectors.errorMessage);
        } catch (error) {
            return null;
        }
    }

    async clickForgotPassword() {
        await this.clickElement(this.selectors.forgotPasswordLink);
    }

    async hasRememberMeOption() {
        return await this.hasElement(this.selectors.rememberMe);
    }
}

/**
 * Trainer Registration Page Object
 */
class TrainerRegistrationPage extends BasePage {
    constructor() {
        super();
        this.url = '/trainer-registration/';
        this.selectors = {
            registrationForm: 'form.registration-form, form#registerform, form[name="registerform"]',
            usernameField: '#user_login, input[name="user_login"], input[name="username"]',
            emailField: '#user_email, input[name="user_email"], input[name="email"]',
            passwordField: '#user_pass, input[name="user_pass"], input[name="password"]',
            confirmPasswordField: '#user_pass_confirm, input[name="user_pass_confirm"]',
            firstNameField: 'input[name="first_name"], input[name="user_firstname"]',
            lastNameField: 'input[name="last_name"], input[name="user_lastname"]',
            phoneField: 'input[name="phone"], input[name="user_phone"]',
            companyField: 'input[name="company"], input[name="user_company"]',
            submitButton: 'input[type="submit"], button[type="submit"]',
            errorMessages: '.error, .notice-error, .registration-errors',
            successMessage: '.success, .notice-success, .registration-success',
            requiredFieldIndicators: '.required, .asterisk, span[title*="required"]'
        };
    }

    async waitForPageReady() {
        await this.waitForElement(this.selectors.registrationForm, 15000);
    }

    async fillRegistrationForm(userData) {
        if (await this.hasElement(this.selectors.usernameField)) {
            await this.fillField(this.selectors.usernameField, userData.username);
        }
        
        if (await this.hasElement(this.selectors.emailField)) {
            await this.fillField(this.selectors.emailField, userData.email);
        }
        
        if (await this.hasElement(this.selectors.passwordField)) {
            await this.fillField(this.selectors.passwordField, userData.password);
        }
        
        if (await this.hasElement(this.selectors.confirmPasswordField)) {
            await this.fillField(this.selectors.confirmPasswordField, userData.password);
        }
        
        if (await this.hasElement(this.selectors.firstNameField)) {
            await this.fillField(this.selectors.firstNameField, userData.firstName);
        }
        
        if (await this.hasElement(this.selectors.lastNameField)) {
            await this.fillField(this.selectors.lastNameField, userData.lastName);
        }
        
        if (await this.hasElement(this.selectors.phoneField)) {
            await this.fillField(this.selectors.phoneField, userData.phone || '555-0123');
        }
        
        if (await this.hasElement(this.selectors.companyField)) {
            await this.fillField(this.selectors.companyField, userData.company || 'Test Company');
        }
    }

    async submitRegistration() {
        await this.clickElement(this.selectors.submitButton);
        await this.page.waitForTimeout(5000); // Wait for submission processing
    }

    async getRegistrationErrors() {
        try {
            const errorElements = await this.page.locator(this.selectors.errorMessages).all();
            const errors = [];
            for (const element of errorElements) {
                const text = await element.textContent();
                if (text && text.trim()) {
                    errors.push(text.trim());
                }
            }
            return errors;
        } catch (error) {
            return [];
        }
    }

    async hasSuccessMessage() {
        return await this.hasElement(this.selectors.successMessage);
    }

    async getRequiredFields() {
        const requiredFields = [];
        const indicators = await this.page.locator(this.selectors.requiredFieldIndicators).all();
        
        for (const indicator of indicators) {
            const parentForm = await indicator.locator('..').first();
            const inputField = await parentForm.locator('input').first();
            const fieldName = await inputField.getAttribute('name');
            if (fieldName) {
                requiredFields.push(fieldName);
            }
        }
        
        return requiredFields;
    }
}

/**
 * Registration Pending Page Object
 */
class RegistrationPendingPage extends BasePage {
    constructor() {
        super();
        this.url = '/registration-pending/';
        this.selectors = {
            pendingMessage: '.pending-message, .approval-notice, .registration-pending',
            statusIndicator: '.status, [data-status="pending"]',
            contactInfo: '.contact-info, .admin-contact',
            nextStepsInfo: '.next-steps, .what-happens-next',
            timeframeInfo: '.timeframe, .approval-time'
        };
    }

    async getPendingMessage() {
        try {
            return await this.getElementText(this.selectors.pendingMessage);
        } catch (error) {
            return await this.getElementText('body'); // Fallback to body content
        }
    }

    async hasContactInformation() {
        return await this.hasElement(this.selectors.contactInfo);
    }

    async hasNextStepsInformation() {
        return await this.hasElement(this.selectors.nextStepsInfo);
    }

    async getApprovalTimeframe() {
        try {
            return await this.getElementText(this.selectors.timeframeInfo);
        } catch (error) {
            return null;
        }
    }
}

/**
 * Account Pending Page Object
 */
class AccountPendingPage extends BasePage {
    constructor() {
        super();
        this.url = '/trainer-account-pending/';
        this.selectors = {
            pendingMessage: '.account-pending, .approval-pending',
            statusDisplay: '.account-status, [data-account-status]',
            adminContact: '.admin-contact, .contact-administrator',
            submittedDate: '.submission-date, .request-date',
            accountDetails: '.account-details, .pending-account-info'
        };
    }

    async getAccountStatus() {
        try {
            return await this.getElementText(this.selectors.statusDisplay);
        } catch (error) {
            return 'pending'; // Default status
        }
    }

    async getSubmissionDate() {
        try {
            return await this.getElementText(this.selectors.submittedDate);
        } catch (error) {
            return null;
        }
    }

    async hasAdminContactInfo() {
        return await this.hasElement(this.selectors.adminContact);
    }
}

/**
 * Account Disabled Page Object
 */
class AccountDisabledPage extends BasePage {
    constructor() {
        super();
        this.url = '/trainer-account-disabled/';
        this.selectors = {
            disabledMessage: '.account-disabled, .account-suspended, .disabled-notice',
            reasonDisplay: '.disable-reason, .suspension-reason',
            reactivationInfo: '.reactivation-info, .restore-account',
            contactInfo: '.contact-admin, .appeal-info',
            disabledDate: '.disabled-date, .suspension-date'
        };
    }

    async getDisabledReason() {
        try {
            return await this.getElementText(this.selectors.reasonDisplay);
        } catch (error) {
            return 'Account has been disabled';
        }
    }

    async hasReactivationInstructions() {
        return await this.hasElement(this.selectors.reactivationInfo);
    }

    async getDisabledDate() {
        try {
            return await this.getElementText(this.selectors.disabledDate);
        } catch (error) {
            return null;
        }
    }

    async hasAppealProcess() {
        return await this.hasElement(this.selectors.contactInfo);
    }
}

/**
 * Find Trainer Page Object (Public Directory)
 */
class FindTrainerPage extends BasePage {
    constructor() {
        super();
        this.url = '/find-trainer/';
        this.selectors = {
            searchForm: '.trainer-search, .directory-search, form[role="search"]',
            searchField: 'input[type="search"], input[name="search"], .search-input',
            searchButton: 'button[type="submit"], input[type="submit"], .search-submit',
            trainerCards: '.trainer-card, .trainer-item, .trainer-listing, article.trainer',
            trainerName: '.trainer-name, .trainer-title, h3, h2',
            trainerLocation: '.trainer-location, .location',
            trainerSpecialty: '.trainer-specialty, .specialties',
            contactButton: '.contact-trainer, .trainer-contact',
            filterOptions: '.filter-options, .directory-filters',
            locationFilter: 'select[name="location"], input[name="location"]',
            specialtyFilter: 'select[name="specialty"], input[name="specialty"]',
            sortOptions: '.sort-options, select[name="sort"]',
            resultsCount: '.results-count, .trainer-count',
            noResultsMessage: '.no-results, .no-trainers-found',
            paginationLinks: '.pagination, .page-numbers'
        };
    }

    async waitForPageReady() {
        await this.waitForElement('body', 10000);
        // Wait for dynamic content to load
        await this.page.waitForTimeout(2000);
    }

    async searchTrainers(searchTerm) {
        if (await this.hasElement(this.selectors.searchField)) {
            await this.fillField(this.selectors.searchField, searchTerm);
            
            if (await this.hasElement(this.selectors.searchButton)) {
                await this.clickElement(this.selectors.searchButton);
            } else {
                await this.page.press(this.selectors.searchField, 'Enter');
            }
            
            // Wait for search results
            await this.page.waitForTimeout(3000);
        }
    }

    async getTrainerCount() {
        return await this.page.locator(this.selectors.trainerCards).count();
    }

    async getTrainerDetails(index = 0) {
        const trainerCard = this.page.locator(this.selectors.trainerCards).nth(index);
        
        if (!(await trainerCard.isVisible())) {
            return null;
        }
        
        const details = {};
        
        try {
            details.name = await trainerCard.locator(this.selectors.trainerName).textContent();
        } catch (error) {
            details.name = 'Unknown';
        }
        
        try {
            details.location = await trainerCard.locator(this.selectors.trainerLocation).textContent();
        } catch (error) {
            details.location = '';
        }
        
        try {
            details.specialty = await trainerCard.locator(this.selectors.trainerSpecialty).textContent();
        } catch (error) {
            details.specialty = '';
        }
        
        return details;
    }

    async filterByLocation(location) {
        if (await this.hasElement(this.selectors.locationFilter)) {
            await this.selectOption(this.selectors.locationFilter, location);
            await this.page.waitForTimeout(2000);
        }
    }

    async filterBySpecialty(specialty) {
        if (await this.hasElement(this.selectors.specialtyFilter)) {
            await this.selectOption(this.selectors.specialtyFilter, specialty);
            await this.page.waitForTimeout(2000);
        }
    }

    async sortResults(sortOption) {
        if (await this.hasElement(this.selectors.sortOptions)) {
            await this.selectOption(this.selectors.sortOptions, sortOption);
            await this.page.waitForTimeout(2000);
        }
    }

    async hasNoResults() {
        return await this.hasElement(this.selectors.noResultsMessage);
    }

    async getResultsCount() {
        try {
            const countText = await this.getElementText(this.selectors.resultsCount);
            const match = countText.match(/\d+/);
            return match ? parseInt(match[0]) : 0;
        } catch (error) {
            return await this.getTrainerCount();
        }
    }
}

/**
 * Documentation Page Object
 */
class DocumentationPage extends BasePage {
    constructor() {
        super();
        this.url = '/documentation/';
        this.selectors = {
            docNavigation: '.doc-nav, .documentation-nav, .help-nav, nav',
            searchField: '.doc-search, .help-search, input[type="search"]',
            searchButton: '.search-submit, button[type="submit"]',
            articleLinks: '.doc-link, .help-link, .article-link, a[href*="help"], a[href*="doc"]',
            articleTitle: '.doc-title, .help-title, .article-title, h1, h2',
            articleContent: '.doc-content, .help-content, .article-content, .content',
            breadcrumbs: '.breadcrumbs, .breadcrumb',
            categoryLinks: '.category-link, .doc-category',
            tableOfContents: '.toc, .table-of-contents',
            relatedArticles: '.related-articles, .see-also',
            backToTop: '.back-to-top, a[href="#top"]',
            printButton: '.print-doc, .print-page',
            lastUpdated: '.last-updated, .updated-date'
        };
    }

    async waitForPageReady() {
        await this.waitForElement('body', 10000);
        await this.page.waitForTimeout(1000);
    }

    async searchDocumentation(searchTerm) {
        if (await this.hasElement(this.selectors.searchField)) {
            await this.fillField(this.selectors.searchField, searchTerm);
            
            if (await this.hasElement(this.selectors.searchButton)) {
                await this.clickElement(this.selectors.searchButton);
            } else {
                await this.page.press(this.selectors.searchField, 'Enter');
            }
            
            await this.page.waitForTimeout(3000);
        }
    }

    async getArticleLinks() {
        const links = await this.page.locator(this.selectors.articleLinks).all();
        const linkData = [];
        
        for (const link of links) {
            const text = await link.textContent();
            const href = await link.getAttribute('href');
            if (text && href) {
                linkData.push({ text: text.trim(), href });
            }
        }
        
        return linkData;
    }

    async navigateToArticle(linkText) {
        const link = this.page.locator(this.selectors.articleLinks).filter({ hasText: linkText });
        if (await link.isVisible()) {
            await link.click();
            await this.page.waitForLoadState('networkidle');
        }
    }

    async hasTableOfContents() {
        return await this.hasElement(this.selectors.tableOfContents);
    }

    async getArticleTitle() {
        try {
            return await this.getElementText(this.selectors.articleTitle);
        } catch (error) {
            return await this.getPageTitle();
        }
    }

    async hasSearchFunctionality() {
        return await this.hasElement(this.selectors.searchField);
    }

    async getLastUpdatedDate() {
        try {
            return await this.getElementText(this.selectors.lastUpdated);
        } catch (error) {
            return null;
        }
    }

    async hasRelatedArticles() {
        return await this.hasElement(this.selectors.relatedArticles);
    }
}

module.exports = {
    TrainingLoginPage,
    TrainerRegistrationPage,
    RegistrationPendingPage,
    AccountPendingPage,
    AccountDisabledPage,
    FindTrainerPage,
    DocumentationPage
};