#!/usr/bin/env node
/**
 * Activation API Client (Phase 3B)
 * Handles communication with ReePoe activation API
 */

const axios = require('axios');
const fs = require('fs');
const path = require('path');
const os = require('os');

const API_BASE_URL = process.env.REEPOE_API_URL || 'https://reepoe-api.onrender.com';

class ActivationClient {
    constructor() {
        this.apiUrl = API_BASE_URL;
        this.activationFile = path.join(os.homedir(), '.reepoe', 'activation.json');
    }
    
    /**
     * Check if user is activated
     */
    async checkActivation(email, version) {
        try {
            const response = await axios.post(`${this.apiUrl}/api/activate/check`, {
                email,
                version
            });
            return response.data;
        } catch (error) {
            if (error.response) {
                return error.response.data;
            }
            throw new Error(`Activation check failed: ${error.message}`);
        }
    }
    
    /**
     * Redeem activation code
     */
    async redeemCode(email, code, version) {
        try {
            const machineId = this.getMachineId();
            
            const response = await axios.post(`${this.apiUrl}/api/activate/redeem`, {
                email,
                code,
                version,
                machine_id: machineId
            });
            
            if (response.data.success) {
                // Save activation locally
                this.saveActivation(response.data);
            }
            
            return response.data;
        } catch (error) {
            if (error.response) {
                return error.response.data;
            }
            throw new Error(`Code redemption failed: ${error.message}`);
        }
    }
    
    /**
     * Join waitlist
     */
    async joinWaitlist(email) {
        try {
            const response = await axios.post(`${this.apiUrl}/api/waitlist/join`, {
                email
            });
            return response.data;
        } catch (error) {
            if (error.response) {
                return error.response.data;
            }
            throw new Error(`Waitlist join failed: ${error.message}`);
        }
    }
    
    /**
     * Get user metrics
     */
    async getUserMetrics(email) {
        try {
            const response = await axios.get(`${this.apiUrl}/api/metrics/user/${email}`);
            return response.data;
        } catch (error) {
            if (error.response) {
                return error.response.data;
            }
            throw new Error(`Failed to get metrics: ${error.message}`);
        }
    }
    
    /**
     * Request extension
     */
    async requestExtension(email, reason) {
        try {
            const response = await axios.post(`${this.apiUrl}/api/users/extend-request`, {
                email,
                reason
            });
            return response.data;
        } catch (error) {
            if (error.response) {
                return error.response.data;
            }
            throw new Error(`Extension request failed: ${error.message}`);
        }
    }
    
    /**
     * Admin: Login
     */
    async adminLogin(email, adminCode) {
        try {
            const response = await axios.post(`${this.apiUrl}/api/admin/auth`, {
                email,
                admin_code: adminCode
            });
            
            if (response.data.success) {
                // Save admin token
                this.saveAdminToken(response.data.admin_token);
            }
            
            return response.data;
        } catch (error) {
            if (error.response) {
                return error.response.data;
            }
            throw new Error(`Admin login failed: ${error.message}`);
        }
    }
    
    /**
     * Admin: List users
     */
    async adminListUsers(status = null, limit = 50) {
        try {
            const token = this.loadAdminToken();
            if (!token) {
                throw new Error('Admin token not found. Run: reepoe admin login');
            }
            
            let url = `${this.apiUrl}/api/admin/users?limit=${limit}`;
            if (status) {
                url += `&status=${status}`;
            }
            
            const response = await axios.get(url, {
                headers: { 'Authorization': `Bearer ${token}` }
            });
            
            return response.data;
        } catch (error) {
            if (error.response) {
                return error.response.data;
            }
            throw new Error(`Failed to list users: ${error.message}`);
        }
    }
    
    /**
     * Admin: Generate codes
     */
    async adminGenerateCodes(count, codeType = 'ALPHA', adminEmail, notes) {
        try {
            const token = this.loadAdminToken();
            if (!token) {
                throw new Error('Admin token not found. Run: reepoe admin login');
            }
            
            const response = await axios.post(`${this.apiUrl}/api/admin/codes/generate`, {
                count,
                code_type: codeType,
                admin_email: adminEmail,
                notes
            }, {
                headers: { 'Authorization': `Bearer ${token}` }
            });
            
            return response.data;
        } catch (error) {
            if (error.response) {
                return error.response.data;
            }
            throw new Error(`Failed to generate codes: ${error.message}`);
        }
    }
    
    /**
     * Admin: Extend user
     */
    async adminExtendUser(email, days, adminEmail) {
        try {
            const token = this.loadAdminToken();
            if (!token) {
                throw new Error('Admin token not found. Run: reepoe admin login');
            }
            
            const response = await axios.post(`${this.apiUrl}/api/admin/users/extend`, {
                email,
                days,
                admin_email: adminEmail
            }, {
                headers: { 'Authorization': `Bearer ${token}` }
            });
            
            return response.data;
        } catch (error) {
            if (error.response) {
                return error.response.data;
            }
            throw new Error(`Failed to extend user: ${error.message}`);
        }
    }
    
    // ========== Local Storage ==========
    
    /**
     * Save activation data locally
     */
    saveActivation(activationData) {
        const configDir = path.join(os.homedir(), '.reepoe');
        if (!fs.existsSync(configDir)) {
            fs.mkdirSync(configDir, { recursive: true, mode: 0o700 });
        }
        
        // Detect cloud environment
        const isCloud = !!(
            process.env.REPL_ID ||
            process.env.CODESPACE_NAME ||
            process.env.GITPOD_WORKSPACE_ID
        );
        
        const data = {
            email: activationData.user?.email || activationData.email,
            token: activationData.token,
            activated_at: activationData.user?.activated_at || new Date().toISOString(),
            expires_at: activationData.user?.expires_at,
            status: activationData.user?.status || 'active',
            api_base: isCloud ? 'https://reepoe-api.onrender.com' : 'http://localhost:8000'
        };
        
        fs.writeFileSync(this.activationFile, JSON.stringify(data, null, 2), { mode: 0o600 });
    }
    
    /**
     * Load activation data
     */
    loadActivation() {
        if (!fs.existsSync(this.activationFile)) {
            return null;
        }
        
        try {
            const data = JSON.parse(fs.readFileSync(this.activationFile, 'utf8'));
            return data;
        } catch (error) {
            return null;
        }
    }
    
    /**
     * Save admin token
     */
    saveAdminToken(token) {
        const configDir = path.join(os.homedir(), '.reepoe');
        const adminFile = path.join(configDir, 'admin_session.json');
        
        if (!fs.existsSync(configDir)) {
            fs.mkdirSync(configDir, { recursive: true, mode: 0o700 });
        }
        
        const data = {
            token,
            created_at: new Date().toISOString(),
            expires_at: new Date(Date.now() + 3600000).toISOString()  // 1 hour
        };
        
        fs.writeFileSync(adminFile, JSON.stringify(data, null, 2), { mode: 0o600 });
    }
    
    /**
     * Load admin token
     */
    loadAdminToken() {
        const adminFile = path.join(os.homedir(), '.reepoe', 'admin_session.json');
        
        if (!fs.existsSync(adminFile)) {
            return null;
        }
        
        try {
            const data = JSON.parse(fs.readFileSync(adminFile, 'utf8'));
            
            // Check if expired
            const expiresAt = new Date(data.expires_at);
            if (new Date() > expiresAt) {
                fs.unlinkSync(adminFile);  // Delete expired token
                return null;
            }
            
            return data.token;
        } catch (error) {
            return null;
        }
    }
    
    /**
     * Get machine ID (for device tracking)
     */
    getMachineId() {
        const crypto = require('crypto');
        const machineInfo = `${os.hostname()}-${os.platform()}-${os.arch()}`;
        return crypto.createHash('sha256').update(machineInfo).digest('hex').substring(0, 16);
    }
}

module.exports = ActivationClient;

