'use client';

import React, { createContext, useContext, useState, useEffect, ReactNode } from 'react';

// Types for cookie consent
export interface CookiePreferences {
  necessary: boolean;
  functional: boolean;
}

export interface ConsentAuditLog {
  timestamp: string;
  action: 'consent_given' | 'consent_updated' | 'consent_withdrawn' | 'settings_opened';
  preferences: CookiePreferences;
  userAgent: string;
  ipAddress?: string;
  sessionId: string;
}

export interface CookieConsentConfig {
  version: string;
  companyName: string;
  privacyPolicyUrl: string;
  cookiePolicyUrl: string;
  dataControllerEmail: string;
  retentionPeriod: number; // days
  enableAuditLog: boolean;
  enableDetailedSettings: boolean;
  showPrivacyNotice: boolean;
}

export interface CookieConsentState {
  hasConsented: boolean;
  preferences: CookiePreferences;
  showBanner: boolean;
  showSettings: boolean;
  consentDate?: string;
  lastUpdated?: string;
  auditLog: ConsentAuditLog[];
}

export interface CookieConsentContextType {
  state: CookieConsentState;
  config: CookieConsentConfig;
  acceptAll: () => void;
  acceptNecessary: () => void;
  acceptSelected: (preferences: Partial<CookiePreferences>) => void;
  showSettings: () => void;
  hideSettings: () => void;
  updatePreferences: (preferences: Partial<CookiePreferences>) => void;
  resetConsent: () => void;
  withdrawConsent: () => void;
  exportConsentData: () => string;
  getConsentSummary: () => any;
}

// Default cookie preferences
const defaultPreferences: CookiePreferences = {
  necessary: true, // Always true, cannot be disabled
  functional: false,
};

// Enterprise configuration
const defaultConfig: CookieConsentConfig = {
  version: '2.0',
  companyName: 'Your Company Name',
  privacyPolicyUrl: '/privacy-policy',
  cookiePolicyUrl: '/cookie-policy',
  dataControllerEmail: 'privacy@yourcompany.com',
  retentionPeriod: 365, // 1 year
  enableAuditLog: true,
  enableDetailedSettings: true,
  showPrivacyNotice: true,
};

// Default state
const defaultState: CookieConsentState = {
  hasConsented: false,
  preferences: defaultPreferences,
  showBanner: false,
  showSettings: false,
  auditLog: [],
};

// Create context
const CookieConsentContext = createContext<CookieConsentContextType | undefined>(undefined);

// Storage keys
const CONSENT_STORAGE_KEY = 'cookie-consent-preferences';
const CONSENT_VERSION = '2.0';

// Utility functions
const generateSessionId = (): string => {
  return Math.random().toString(36).substring(2) + Date.now().toString(36);
};

const createAuditLogEntry = (
  action: ConsentAuditLog['action'],
  preferences: CookiePreferences
): ConsentAuditLog => {
  return {
    timestamp: new Date().toISOString(),
    action,
    preferences,
    userAgent: typeof window !== 'undefined' ? window.navigator.userAgent : '',
    sessionId: generateSessionId(),
  };
};

// Provider component
export const CookieConsentProvider: React.FC<{ 
  children: ReactNode;
  config?: Partial<CookieConsentConfig>;
}> = ({ children, config: customConfig }) => {
  const [state, setState] = useState<CookieConsentState>(defaultState);
  const config = { ...defaultConfig, ...customConfig };

  // Load saved preferences on mount
  useEffect(() => {
    const loadSavedPreferences = () => {
      try {
        const saved = localStorage.getItem(CONSENT_STORAGE_KEY);
        if (saved) {
          const parsed = JSON.parse(saved);
          // Check if saved version matches current version
          if (parsed.version === CONSENT_VERSION) {
            setState({
              hasConsented: true,
              preferences: parsed.preferences,
              showBanner: false,
              showSettings: false,
              consentDate: parsed.consentDate,
              lastUpdated: parsed.lastUpdated,
              auditLog: parsed.auditLog || [],
            });
            return;
          }
        }
      } catch (error) {
        console.warn('Failed to load cookie preferences:', error);
      }
      
      // Show banner if no valid consent found
      setState(prev => ({ ...prev, showBanner: true }));
    };

    loadSavedPreferences();
  }, []);

  // Save preferences to localStorage with audit logging
  const savePreferences = (preferences: CookiePreferences, action: ConsentAuditLog['action'] = 'consent_given') => {
    try {
      const auditEntry = config.enableAuditLog ? createAuditLogEntry(action, preferences) : null;
      
      const data = {
        version: CONSENT_VERSION,
        preferences,
        timestamp: new Date().toISOString(),
        consentDate: state.consentDate || new Date().toISOString(),
        lastUpdated: new Date().toISOString(),
        auditLog: auditEntry ? [...state.auditLog, auditEntry] : state.auditLog,
      };
      
      localStorage.setItem(CONSENT_STORAGE_KEY, JSON.stringify(data));
      
      // Update state with audit log
      if (auditEntry) {
        setState(prev => ({
          ...prev,
          auditLog: [...prev.auditLog, auditEntry],
        }));
      }
    } catch (error) {
      console.warn('Failed to save cookie preferences:', error);
    }
  };

  // Accept all cookies
  const acceptAll = () => {
    const allAccepted: CookiePreferences = {
      necessary: true,
      functional: true,
    };
    
    setState(prev => ({
      ...prev,
      hasConsented: true,
      preferences: allAccepted,
      showBanner: false,
      showSettings: false,
      consentDate: prev.consentDate || new Date().toISOString(),
      lastUpdated: new Date().toISOString(),
    }));
    
    savePreferences(allAccepted, 'consent_given');
  };

  // Accept only necessary cookies
  const acceptNecessary = () => {
    const necessaryOnly: CookiePreferences = {
      necessary: true,
      functional: false,
    };
    
    setState(prev => ({
      ...prev,
      hasConsented: true,
      preferences: necessaryOnly,
      showBanner: false,
      showSettings: false,
      consentDate: prev.consentDate || new Date().toISOString(),
      lastUpdated: new Date().toISOString(),
    }));
    
    savePreferences(necessaryOnly, 'consent_given');
  };

  // Accept selected cookies
  const acceptSelected = (preferences: Partial<CookiePreferences>) => {
    const newPreferences: CookiePreferences = {
      necessary: true, // Always true
      functional: preferences.functional ?? false,
    };
    
    setState(prev => ({
      ...prev,
      hasConsented: true,
      preferences: newPreferences,
      showBanner: false,
      showSettings: false,
      consentDate: prev.consentDate || new Date().toISOString(),
      lastUpdated: new Date().toISOString(),
    }));
    
    savePreferences(newPreferences, 'consent_updated');
  };

  // Show settings modal
  const showSettings = () => {
    setState(prev => ({ ...prev, showSettings: true }));
    
    // Log settings opened
    if (config.enableAuditLog) {
      const auditEntry = createAuditLogEntry('settings_opened', state.preferences);
      setState(prev => ({
        ...prev,
        auditLog: [...prev.auditLog, auditEntry],
      }));
    }
  };

  // Hide settings modal
  const hideSettings = () => {
    setState(prev => ({ ...prev, showSettings: false }));
  };

  // Update preferences (for settings modal)
  const updatePreferences = (preferences: Partial<CookiePreferences>) => {
    setState(prev => ({
      ...prev,
      preferences: {
        ...prev.preferences,
        ...preferences,
        necessary: true, // Always keep necessary as true
      },
    }));
  };

  // Reset consent (for testing or user request)
  const resetConsent = () => {
    try {
      localStorage.removeItem(CONSENT_STORAGE_KEY);
    } catch (error) {
      console.warn('Failed to reset cookie preferences:', error);
    }
    
    setState({
      hasConsented: false,
      preferences: defaultPreferences,
      showBanner: true,
      showSettings: false,
      auditLog: [],
    });
  };

  // Withdraw consent (GDPR compliance)
  const withdrawConsent = () => {
    try {
      localStorage.removeItem(CONSENT_STORAGE_KEY);
    } catch (error) {
      console.warn('Failed to withdraw consent:', error);
    }
    
    const auditEntry = config.enableAuditLog ? createAuditLogEntry('consent_withdrawn', defaultPreferences) : null;
    
    setState({
      hasConsented: false,
      preferences: defaultPreferences,
      showBanner: true,
      showSettings: false,
      auditLog: auditEntry ? [...state.auditLog, auditEntry] : state.auditLog,
    });
  };

  // Export consent data (GDPR compliance)
  const exportConsentData = (): string => {
    const exportData = {
      consentData: {
        hasConsented: state.hasConsented,
        preferences: state.preferences,
        consentDate: state.consentDate,
        lastUpdated: state.lastUpdated,
        auditLog: state.auditLog,
      },
      config: {
        version: config.version,
        companyName: config.companyName,
        retentionPeriod: config.retentionPeriod,
      },
      exportDate: new Date().toISOString(),
    };
    
    return JSON.stringify(exportData, null, 2);
  };

  // Get consent summary
  const getConsentSummary = () => {
    return {
      hasConsented: state.hasConsented,
      preferences: state.preferences,
      consentDate: state.consentDate,
      lastUpdated: state.lastUpdated,
      auditLogCount: state.auditLog.length,
      config: {
        version: config.version,
        companyName: config.companyName,
        retentionPeriod: config.retentionPeriod,
      },
    };
  };

  const contextValue: CookieConsentContextType = {
    state,
    config,
    acceptAll,
    acceptNecessary,
    acceptSelected,
    showSettings,
    hideSettings,
    updatePreferences,
    resetConsent,
    withdrawConsent,
    exportConsentData,
    getConsentSummary,
  };

  return (
    <CookieConsentContext.Provider value={contextValue}>
      {children}
    </CookieConsentContext.Provider>
  );
};

// Hook to use cookie consent context
export const useCookieConsent = (): CookieConsentContextType => {
  const context = useContext(CookieConsentContext);
  if (context === undefined) {
    throw new Error('useCookieConsent must be used within a CookieConsentProvider');
  }
  return context;
};

// Hook to check if specific cookie type is allowed
export const useCookiePermission = (type: keyof CookiePreferences): boolean => {
  const { state } = useCookieConsent();
  return state.preferences[type];
};

// Hook for functional features (only runs if functional cookies are allowed)
export const useFunctional = () => {
  const { state } = useCookieConsent();
  const isEnabled = state.preferences.functional && state.hasConsented;

  const saveUserPreference = (key: string, value: any) => {
    if (isEnabled && typeof window !== 'undefined') {
      try {
        localStorage.setItem(`user-preference-${key}`, JSON.stringify(value));
      } catch (error) {
        console.warn('Failed to save user preference:', error);
      }
    }
  };

  const loadUserPreference = (key: string, defaultValue?: any) => {
    if (isEnabled && typeof window !== 'undefined') {
      try {
        const saved = localStorage.getItem(`user-preference-${key}`);
        return saved ? JSON.parse(saved) : defaultValue;
      } catch (error) {
        console.warn('Failed to load user preference:', error);
        return defaultValue;
      }
    }
    return defaultValue;
  };

  const rememberUserAction = (action: string, data?: any) => {
    if (isEnabled) {
      console.log('User Action Remembered:', action, data);
      // Implement your user action tracking logic here
    }
  };

  return {
    saveUserPreference,
    loadUserPreference,
    rememberUserAction,
    isEnabled,
  };
};
