/**
 * NIS2 Agile - API Client
 *
 * Client JavaScript per comunicare con il backend REST API.
 */

class NIS2API {
    constructor(baseUrl = '/api') {
        this.baseUrl = baseUrl;
        this.token = localStorage.getItem('nis2_access_token');
        this.refreshToken = localStorage.getItem('nis2_refresh_token');
        this.orgId = localStorage.getItem('nis2_org_id');
    }

    // ═══════════════════════════════════════════════════════════════════
    // HTTP Methods
    // ═══════════════════════════════════════════════════════════════════

    async request(method, endpoint, data = null, options = {}) {
        const url = `${this.baseUrl}${endpoint}`;
        const headers = {
            'Content-Type': 'application/json',
        };

        if (this.token) {
            headers['Authorization'] = `Bearer ${this.token}`;
        }

        if (this.orgId) {
            headers['X-Organization-Id'] = this.orgId;
        }

        const config = { method, headers };

        if (data && (method === 'POST' || method === 'PUT')) {
            config.body = JSON.stringify(data);
        }

        try {
            const response = await fetch(url, config);
            const json = await response.json();

            // Token expired - try refresh
            if (response.status === 401 && this.refreshToken && !options._isRetry) {
                const refreshed = await this.doRefreshToken();
                if (refreshed) {
                    return this.request(method, endpoint, data, { ...options, _isRetry: true });
                }
            }

            if (!json.success && !options.silent) {
                console.error(`[API] ${method} ${endpoint}:`, json.message);
            }

            return json;
        } catch (error) {
            console.error(`[API] Network error: ${method} ${endpoint}`, error);
            const msg = typeof I18n !== 'undefined' ? I18n.t('msg.error_connection') : 'Errore di connessione al server';
            return { success: false, message: msg };
        }
    }

    get(endpoint) { return this.request('GET', endpoint); }
    post(endpoint, data) { return this.request('POST', endpoint, data); }
    put(endpoint, data) { return this.request('PUT', endpoint, data); }
    del(endpoint) { return this.request('DELETE', endpoint); }

    // ═══════════════════════════════════════════════════════════════════
    // Auth
    // ═══════════════════════════════════════════════════════════════════

    async login(email, password) {
        const result = await this.post('/auth/login', { email, password });
        if (result.success) {
            this.setTokens(result.data.access_token, result.data.refresh_token);
            this.setUserRole(result.data.user.role);
            if (result.data.organizations && result.data.organizations.length > 0) {
                const primary = result.data.organizations.find(o => o.is_primary) || result.data.organizations[0];
                this.setOrganization(primary.organization_id);
            }
        }
        return result;
    }

    async register(email, password, fullName, roleOrType = 'azienda') {
        // Supporta sia i nuovi role NIS2 diretti (compliance_manager, org_admin, etc.)
        // che il vecchio user_type (azienda, consultant) per retrocompatibilità
        const result = await this.post('/auth/register', {
            email, password, full_name: fullName,
            role: roleOrType,
            user_type: roleOrType,   // backward compat
        });
        if (result.success) {
            this.setTokens(result.data.access_token, result.data.refresh_token);
            localStorage.setItem('nis2_user_role', result.data.user.role);
        }
        return result;
    }

    async doRefreshToken() {
        try {
            const result = await this.post('/auth/refresh', { refresh_token: this.refreshToken });
            if (result.success) {
                this.setTokens(result.data.access_token, result.data.refresh_token);
                return true;
            }
        } catch (e) { /* ignore */ }
        this.logout();
        return false;
    }

    logout() {
        this.post('/auth/logout', {}).catch(() => {});
        this.clearTokens();
        window.location.href = '/login.html';
    }

    getMe() { return this.get('/auth/me'); }

    setTokens(access, refresh) {
        this.token = access;
        this.refreshToken = refresh;
        localStorage.setItem('nis2_access_token', access);
        localStorage.setItem('nis2_refresh_token', refresh);
    }

    clearTokens() {
        this.token = null;
        this.refreshToken = null;
        this.orgId = null;
        localStorage.removeItem('nis2_access_token');
        localStorage.removeItem('nis2_refresh_token');
        localStorage.removeItem('nis2_org_id');
        localStorage.removeItem('nis2_user_role');
    }

    // Salva ruolo utente al login
    setUserRole(role) {
        localStorage.setItem('nis2_user_role', role);
    }

    getUserRole() {
        return localStorage.getItem('nis2_user_role');
    }

    isConsultant() {
        return this.getUserRole() === 'consultant';
    }

    setOrganization(orgId) {
        this.orgId = orgId;
        localStorage.setItem('nis2_org_id', orgId);
    }

    isAuthenticated() {
        return !!this.token;
    }

    // ═══════════════════════════════════════════════════════════════════
    // Organizations
    // ═══════════════════════════════════════════════════════════════════

    createOrganization(data) { return this.post('/organizations/create', data); }
    getCurrentOrg() { return this.get('/organizations/current'); }
    listOrganizations() { return this.get('/organizations/list'); }
    updateOrganization(id, data) { return this.put(`/organizations/${id}`, data); }
    classifyEntity(data) { return this.post('/organizations/classify', data); }

    // ═══════════════════════════════════════════════════════════════════
    // Assessments
    // ═══════════════════════════════════════════════════════════════════

    listAssessments() { return this.get('/assessments/list'); }
    createAssessment(data) { return this.post('/assessments/create', data); }
    getAssessment(id) { return this.get(`/assessments/${id}`); }
    getAssessmentQuestions(id) { return this.get(`/assessments/${id}/questions`); }
    saveAssessmentResponse(id, data) { return this.post(`/assessments/${id}/respond`, data); }
    completeAssessment(id) { return this.post(`/assessments/${id}/complete`, {}); }
    getAssessmentReport(id) { return this.get(`/assessments/${id}/report`); }
    aiAnalyzeAssessment(id) { return this.post(`/assessments/${id}/ai-analyze`, {}); }

    // ═══════════════════════════════════════════════════════════════════
    // Dashboard
    // ═══════════════════════════════════════════════════════════════════

    getDashboardOverview() { return this.get('/dashboard/overview'); }
    getComplianceScore() { return this.get('/dashboard/compliance-score'); }
    getUpcomingDeadlines() { return this.get('/dashboard/upcoming-deadlines'); }
    getRecentActivity() { return this.get('/dashboard/recent-activity'); }
    getRiskHeatmap() { return this.get('/dashboard/risk-heatmap'); }

    // ═══════════════════════════════════════════════════════════════════
    // Risks
    // ═══════════════════════════════════════════════════════════════════

    listRisks(params = {}) { return this.get('/risks/list?' + new URLSearchParams(params)); }
    createRisk(data) { return this.post('/risks/create', data); }
    getRisk(id) { return this.get(`/risks/${id}`); }
    updateRisk(id, data) { return this.put(`/risks/${id}`, data); }
    deleteRisk(id) { return this.del(`/risks/${id}`); }
    getRiskMatrix() { return this.get('/risks/matrix'); }
    aiSuggestRisks() { return this.post('/risks/ai-suggest', {}); }
    // FAIR quantitativo + KRI (P2)
    computeFair(id, data) { return this.post(`/risks/${id}/fair`, data); }
    getFairRegister() { return this.get('/risks/fairRegister'); }
    listKri() { return this.get('/risks/kri'); }
    createKri(data) { return this.post('/risks/kri', data); }
    updateKri(id, data) { return this.put(`/risks/kri/${id}`, data); }

    // ═══════════════════════════════════════════════════════════════════
    // Incidents
    // ═══════════════════════════════════════════════════════════════════

    listIncidents(params = {}) { return this.get('/incidents/list?' + new URLSearchParams(params)); }
    createIncident(data) { return this.post('/incidents/create', data); }
    getIncident(id) { return this.get(`/incidents/${id}`); }
    updateIncident(id, data) { return this.put(`/incidents/${id}`, data); }
    sendEarlyWarning(id) { return this.post(`/incidents/${id}/early-warning`, {}); }
    sendNotification(id) { return this.post(`/incidents/${id}/notification`, {}); }
    sendFinalReport(id) { return this.post(`/incidents/${id}/final-report`, {}); }
    aiClassifyIncident(id) { return this.post(`/incidents/${id}/aiClassify`, {}); }
    getIncidentMetrics(id) { return this.get(`/incidents/${id}/metrics`); }
    getIncidentPir(id) { return this.get(`/incidents/${id}/pir`); }
    saveIncidentPir(id, data) { return this.post(`/incidents/${id}/pir`, data); }

    // ═══════════════════════════════════════════════════════════════════
    // Policies
    // ═══════════════════════════════════════════════════════════════════

    listPolicies(params = {}) { return this.get('/policies/list?' + new URLSearchParams(params)); }
    createPolicy(data) { return this.post('/policies/create', data); }
    getPolicy(id) { return this.get(`/policies/${id}`); }
    updatePolicy(id, data) { return this.put(`/policies/${id}`, data); }
    approvePolicy(id) { return this.post(`/policies/${id}/approve`, {}); }
    aiGeneratePolicy(category) { return this.post('/policies/ai-generate', { category }); }
    getPolicyTemplates() { return this.get('/policies/templates'); }

    // ═══════════════════════════════════════════════════════════════════
    // Supply Chain
    // ═══════════════════════════════════════════════════════════════════

    listSuppliers() { return this.get('/supply-chain/list'); }
    createSupplier(data) { return this.post('/supply-chain/create', data); }
    getSupplier(id) { return this.get(`/supply-chain/${id}`); }
    updateSupplier(id, data) { return this.put(`/supply-chain/${id}`, data); }
    assessSupplier(id, data) { return this.post(`/supply-chain/${id}/assess`, data); }

    // ═══════════════════════════════════════════════════════════════════
    // Training
    // ═══════════════════════════════════════════════════════════════════

    listCourses() { return this.get('/training/courses'); }
    getMyTraining() { return this.get('/training/assignments'); }
    getTrainingCompliance() { return this.get('/training/compliance-status'); }

    // ═══════════════════════════════════════════════════════════════════
    // Assets
    // ═══════════════════════════════════════════════════════════════════

    listAssets(params = {}) { return this.get('/assets/list?' + new URLSearchParams(params)); }
    createAsset(data) { return this.post('/assets/create', data); }
    getAsset(id) { return this.get(`/assets/${id}`); }
    updateAsset(id, data) { return this.put(`/assets/${id}`, data); }
    deleteAsset(id) { return this.delete(`/assets/${id}`); }
    // NIS2 relevance scoring (GV.OC-04)
    getScoringGrid() { return this.get('/assets/scoringGrid'); }
    scoreAsset(id, criteria) { return this.post(`/assets/${id}/score`, { criteria }); }
    listRelevantSystems() { return this.get('/assets/relevantSystems'); }
    importAssets(data) { return this.post('/assets/import', data); }            // P2 import CMDB/CSV
    getControlsMonitoring() { return this.get('/audit/controlsMonitoring'); }
    getAcnRequirements() { return this.get('/audit/acnRequirements'); }                                  // requisiti ACN per org
    updateAcnRequirement(id, status, note) { return this.put(`/audit/acnRequirements/${id}`, { status, evidence_note: note }); }
    sendSupplierQuestionnaire(id, email) { return this.post(`/supply-chain/${id}/send-questionnaire`, email ? { email } : {}); }  // self-assessment fornitore (link esterno)
    getSupplierQuestionnaireStatus(id) { return this.get(`/supply-chain/${id}/questionnaire-status`); }    // P1 continuous control monitoring (JWT)

    // ═══════════════════════════════════════════════════════════════════
    // Audit
    // ═══════════════════════════════════════════════════════════════════

    listControls() { return this.get('/audit/controls'); }
    updateControl(id, data) { return this.put(`/audit/controls/${id}`, data); }
    generateComplianceReport() { return this.get('/audit/report'); }
    getAuditLogs(params = {}) { return this.get('/audit/logs?' + new URLSearchParams(params)); }
    getIsoMapping() { return this.get('/audit/iso27001-mapping'); }
    getExecutiveReportUrl() { return this.baseUrl + '/audit/executive-report'; }
    getExportUrl(type) { return this.baseUrl + '/audit/export?type=' + type; }

    // ═══════════════════════════════════════════════════════════════════
    // Onboarding
    // ═══════════════════════════════════════════════════════════════════

    async uploadVisura(file) {
        const formData = new FormData();
        formData.append('visura', file);
        const headers = { 'Authorization': 'Bearer ' + this.token };
        if (this.orgId) headers['X-Organization-Id'] = this.orgId;
        try {
            const response = await fetch(this.baseUrl + '/onboarding/upload-visura', {
                method: 'POST',
                headers,
                body: formData,
            });
            return response.json();
        } catch (error) {
            const msg = typeof I18n !== 'undefined' ? I18n.t('msg.error_connection') : 'Errore di connessione al server';
            return { success: false, message: msg };
        }
    }

    fetchCompany(vatNumber) { return this.post('/onboarding/fetch-company', { vat_number: vatNumber }); }
    completeOnboarding(data) { return this.post('/onboarding/complete', data); }

    // ═══════════════════════════════════════════════════════════════════
    // Non-Conformity & CAPA
    // ═══════════════════════════════════════════════════════════════════

    listNCRs(params = {}) { return this.get('/ncr/list?' + new URLSearchParams(params)); }
    createNCR(data) { return this.post('/ncr/create', data); }
    getNCR(id) { return this.get(`/ncr/${id}`); }
    updateNCR(id, data) { return this.put(`/ncr/${id}`, data); }
    addCapa(ncrId, data) { return this.post(`/ncr/${ncrId}/capa`, data); }
    updateCapa(capaId, data) { return this.put(`/ncr/capa/${capaId}`, data); }
    createNCRsFromAssessment(assessmentId) { return this.post('/ncr/from-assessment', { assessment_id: assessmentId }); }
    getNCRStats() { return this.get('/ncr/stats'); }

    // ═══════════════════════════════════════════════════════════════════
    // Feedback & Segnalazioni
    // ═══════════════════════════════════════════════════════════════════

    submitFeedback(data)           { return this.post('/feedback/submit', data); }
    getMyFeedback()                { return this.get('/feedback/mine'); }
    listFeedback(params = {})      { return this.get('/feedback/list?' + new URLSearchParams(params)); }
    getFeedback(id)                { return this.get(`/feedback/${id}`); }
    updateFeedback(id, data)       { return this.put(`/feedback/${id}`, data); }
    resolveFeedback(id, password)  { return this.post(`/feedback/${id}/resolve`, { password }); }
}

// Singleton globale
const api = new NIS2API();
