/**
 * Secure API service that replaces direct Firestore access
 * All data operations go through authenticated cloud functions
 */

import { Employee, EmployeeReport, Submission, CompanyReport, UserOrganization, Organization } from '../types';
import { API_URL } from '../constants';

interface ApiResponse<T> {
    success: boolean;
    data?: T;
    error?: string;
    message?: string;
}

interface GetOrgData {
    org: Organization;
    success: boolean;
}

interface OrgData {
    id: string;
    name: string;
    industry?: string;
    size?: string;
    description?: string;
    mission?: string;
    vision?: string;
    values?: string;
    foundingYear?: string;
    evolution?: string;
    majorMilestones?: string;
    advantages?: string;
    vulnerabilities?: string;
    competitors?: string;
    marketPosition?: string;
    currentChallenges?: string;
    shortTermGoals?: string;
    longTermGoals?: string;
    keyMetrics?: string;
    cultureDescription?: string;
    workEnvironment?: string;
    leadershipStyle?: string;
    communicationStyle?: string;
    additionalContext?: string;
    onboardingCompleted?: boolean;
    [key: string]: any;
}

interface GetSubmissions {
    submissions: Submission[];
}

interface GetUserOrganizations {
    organizations: UserOrganization[];
}

interface CreateOrganization {
    success: boolean;
    orgId: string;
    name: string;
    role: "owner" | "admin" | "employee";
    onboardingCompleted: boolean;
    joinedAt: number;
    subscription: any;
    requiresSubscription: boolean;
}

interface JoinOrganization {
    orgId: string;
    name: string;
    role: "owner" | "admin" | "employee";
    onboardingCompleted: boolean;
    joinedAt: number;
    success: boolean;
}

interface CreateInvitation {
    success: boolean;
    code: string;
    employee: Employee;
    inviteLink: string;
    message: "Invitation sent successfully";
}

interface ConsumeInvitation {
    success: boolean;
    orgId: string;
    message: string;
}

interface CreateCheckoutSession {
    success: true;
    sessionId: string;
    sessionUrl: string;
    customerId: string;
}

class SecureApiService {
    private async makeRequest<T>(
        endpoint: string,
        method: 'GET' | 'POST' | 'PUT' | 'DELETE' = 'GET',
        data?: any,
        requireAuth: boolean = true
    ): Promise<T> {
        const url = `${API_URL}/${endpoint}`;

        const headers: Record<string, string> = {
            'Content-Type': 'application/json',
        };

        // Add auth token for authenticated requests
        if (requireAuth) {
            const authToken = localStorage.getItem('auditly_auth_token');
            if (!authToken) {
                throw new Error('Authentication token not found. Please log in again.');
            }
            headers['Authorization'] = `Bearer ${authToken}`;
        }

        const config: RequestInit = {
            method,
            headers,
        };

        if (data && method !== 'GET') {
            config.body = JSON.stringify(data);
        }

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

            if (!response.ok) {
                // Handle auth errors specifically
                if (requireAuth && (response.status === 401 || response.status === 403)) {
                    // Clear invalid token and redirect to login
                    localStorage.removeItem('auditly_auth_token');
                    localStorage.removeItem('auditly_demo_session');
                    throw new Error('Authentication failed. Please log in again.');
                }

                const errorData = await response.json().catch(() => ({ error: 'Unknown error' }));
                throw new Error(errorData.error || `HTTP ${response.status}`);
            }

            const result = await response.json();

            if (!result.success) {
                throw new Error(result.error || 'Request failed');
            }

            return result;
        } catch (error) {
            console.error(`API request failed: ${method} ${endpoint}`, error);
            throw error;
        }
    }

    // Organization Data Methods
    async getOrgData(): Promise<Organization> {
        const response = await this.makeRequest<{ org: Organization }>(
            'getOrgData', 'GET', null, true
        );
        return response.org;
    }

    async updateOrgData(data: Partial<OrgData>): Promise<void> {
        await this.makeRequest(
            'updateOrgData',
            'PUT',
            { data }
        );
    }

    // Employee Methods
    async getEmployees(): Promise<Employee[]> {
        const response = await this.makeRequest<{ employees: Employee[] }>(
            'getEmployees'
        );
        return response.employees;
    }

    async upsertEmployee(employeeData: Partial<Employee>): Promise<Employee> {
        const response = await this.makeRequest<{ employee: Employee }>(
            'upsertEmployee',
            'POST',
            { employeeData }
        );
        return response.employee;
    }

    // Submission Methods
    async getSubmissions(): Promise<GetSubmissions> {
        const response = await this.makeRequest<{ submissions: Submission[] }>(
            'getSubmissions'
        );
        return response;
    }

    // Report Methods
    async getReports(): Promise<Record<string, EmployeeReport>> {
        const response = await this.makeRequest<{ reports: Record<string, EmployeeReport> }>(
            'getReports'
        );
        return response.reports;
    }

    async saveReport(employeeId: string, reportData: Partial<EmployeeReport>): Promise<EmployeeReport> {
        const response = await this.makeRequest<{ report: EmployeeReport }>(
            'saveReport',
            'POST',
            { employeeId, reportData }
        );
        return response.report;
    }

    // Company Report Methods
    async getCompanyReports(): Promise<CompanyReport[]> {
        const response = await this.makeRequest<{ reports: CompanyReport[] }>(
            'getCompanyReports'
        );
        return response.reports;
    }

    async saveCompanyReport(report: any): Promise<string> {
        const response = await this.makeRequest<{ reportId: string }>(
            'saveCompanyReport',
            'POST',
            { report }
        );
        return response.reportId;
    }

    // Existing API methods (these already use cloud functions)
    async sendOTP(email: string, inviteCode?: string) {
        return this.makeRequest('sendOTP', 'POST', { email, inviteCode }, false);
    }

    async verifyOTP(email: string, otp: string) {
        return this.makeRequest('verifyOTP', 'POST', { email, otp }, false);
    }

    async createInvitation({ name, email, role, department }: { name: string, email: string, role?: string, department?: string }): Promise<CreateInvitation> {
        return this.makeRequest('createInvitation', 'POST', { name, email, role, department });
    }

    async getInvitationStatus(code: string): Promise<{ used: boolean; employee: any; invite?: any } | null> {
        try {
            return await this.makeRequest(`getInvitationStatus?code=${code}`);
        } catch (error) {
            return null;
        }
    }

    async consumeInvitation(code: string, userId?: string): Promise<ConsumeInvitation> {
        return this.makeRequest('consumeInvitation', 'POST', { code, userId });
    }

    async submitEmployeeAnswers(employeeId: string, answers: any, inviteCode?: string) {
        return this.makeRequest('submitEmployeeAnswers', 'POST', { employeeId, answers, inviteCode });
    }

    async generateEmployeeReport(employee: any, submission: any, companyWiki?: any) {
        return this.makeRequest('generateEmployeeReport', 'POST', { employee, submission, companyWiki });
    }

    async generateCompanyWiki(org: any, submissions: any[] = []): Promise<CompanyReport> {
        const response = await this.makeRequest<{ report: CompanyReport }>('generateCompanyReport', 'POST', { org, submissions });
        return response.report;
    }

    async chat(message: string, employeeId?: string, context?: any, mentions?: any[], attachments?: any[]) {
        return this.makeRequest('chat', 'POST', { message, employeeId, context, mentions, attachments });
    }

    async createOrganization(name: string): Promise<CreateOrganization> {
        return this.makeRequest('createOrganization', 'POST', { name });
    }

    async getUserOrganizations(): Promise<GetUserOrganizations> {
        return this.makeRequest('getUserOrganizations', 'GET', null, true);
    }

    async joinOrganization(inviteCode: string): Promise<JoinOrganization> {
        return this.makeRequest('joinOrganization', 'POST', { inviteCode });
    }

    async createCheckoutSession(userEmail: string, priceId?: string): Promise<CreateCheckoutSession> {
        return this.makeRequest('createCheckoutSession', 'POST', { userEmail, priceId });
    }

    async getSubscriptionStatus() {
        return this.makeRequest('getSubscriptionStatus');
    }

    // Image Storage Methods
    async uploadImage(
        imageData: {
            collectionName: string;
            documentId: string;
            dataUrl: string;
            filename: string;
            originalSize: number;
            compressedSize: number;
            width: number;
            height: number;
        }
    ): Promise<{ success: boolean; imageId: string }> {
        return this.makeRequest('uploadImage', 'POST', { imageData });
    }

    async getImage(
        collectionName: string,
        documentId: string
    ): Promise<{
        id: string;
        dataUrl: string;
        filename: string;
        originalSize: number;
        compressedSize: number;
        uploadedAt: number;
        width: number;
        height: number;
    } | null> {
        try {
            const response = await this.makeRequest<{ image: any }>(
                `getImage?collectionName=${collectionName}&documentId=${documentId}`
            );
            return response.image || null;
        } catch (error) {
            console.warn('Image not found:', error);
            return null;
        }
    }

    async deleteImage(
        collectionName: string,
        documentId: string
    ): Promise<boolean> {
        try {
            await this.makeRequest('deleteImage', 'DELETE', { collectionName, documentId });
            return true;
        } catch (error) {
            console.error('Failed to delete image:', error);
            return false;
        }
    }

    // Migration Methods
    async migrateOwnersFromEmployees(): Promise<{ success: boolean; migratedCount: number; ownerInfo?: any }> {
        return this.makeRequest('migrateOwnersFromEmployees', 'POST');
    }

    // Onboarding Methods
    async completeOnboarding(onboardingData: any): Promise<{ success: boolean; error?: string }> {
        return this.makeRequest('onboarding/complete', 'POST', onboardingData);
    }

    async getOnboardingQuestions(): Promise<{ questions: any; completed: boolean; lastStep?: number }> {
        return this.makeRequest('getOrgData', 'GET');
    }
}

// Export a singleton instance
export const secureApi = new SecureApiService();
export default secureApi;
