import { supabase } from '@/integrations/supabase/client';
import { parseISO, isValid } from 'date-fns';
import { formatDateEST, formatRelativeDateEST } from '@/lib/timezoneUtils';

/**
 * Formats a date string into MM/dd/yyyy in EST.
 */
export const formatDate = (dateString) => {
  if (!dateString) return '';
  return formatDateEST(dateString) || '';
};

export const validateEmail = (email) => {
  if (!email || typeof email !== 'string') return false;
  try {
    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    return emailRegex.test(email.trim());
  } catch (error) {
    console.error('Error validating email:', error);
    return false;
  }
};

export const validateAndParseDate = (dateInput) => {
  if (!dateInput) return null;
  try {
    let date;
    if (typeof dateInput === 'string') {
      const trimmed = dateInput.trim();
      if (trimmed.includes('T')) {
        date = parseISO(trimmed);
      } else if (trimmed.match(/^\d{4}-\d{2}-\d{2}$/)) {
        date = new Date(trimmed + 'T00:00:00Z');
      } else {
        date = new Date(trimmed);
      }
    } else if (dateInput instanceof Date) {
      date = dateInput;
    } else if (typeof dateInput === 'number') {
      date = new Date(dateInput);
    } else {
      return null;
    }
    
    if (!isValid(date) || isNaN(date.getTime())) {
      return null;
    }
    return date;
  } catch (e) {
    console.error('Error parsing date in validateAndParseDate:', e, dateInput);
    return null;
  }
};

export const isValidDate = (date) => {
  if (!date) return false;
  if (!(date instanceof Date)) return false;
  return isValid(date) && !isNaN(date.getTime());
};

export const validateOwnerUpdate = (formData) => {
  const errors = [];
  if (!formData?.owner_name || formData.owner_name.trim() === '') errors.push('Owner name is required.');
  if (!formData?.property_address || formData.property_address.trim() === '') errors.push('Property address is required.');
  if (formData?.email && !validateEmail(formData.email)) errors.push('Invalid email format.');
  if (formData?.balance !== '' && formData?.balance !== null && formData?.balance !== undefined) {
    const balanceNum = parseFloat(formData.balance);
    if (isNaN(balanceNum)) errors.push('Balance must be a valid number.');
  }
  return errors;
};

export const getAssociationVariables = async (clientId) => {
  if (!clientId) return {};
  try {
    const [{ data: customVars }, { data: assocInfo }, { data: clientInfo }] = await Promise.all([
      supabase.from('custom_variables').select('variable_name, predefined_value').eq('client_id', clientId),
      supabase.from('association_info').select('website, email').eq('id', clientId).maybeSingle(),
      supabase.from('clients').select('name, email, phone, company').eq('id', clientId).maybeSingle()
    ]);
    const vars = {};
    if (customVars) customVars.forEach(v => vars[v.variable_name] = v.predefined_value || '');
    if (assocInfo) {
      vars['association_website'] = assocInfo.website || '';
      vars['association_email'] = assocInfo.email || '';
    }
    if (clientInfo) {
      vars['association_name'] = clientInfo.name || '';
      vars['association_phone'] = clientInfo.phone || '';
      vars['association_company'] = clientInfo.company || '';
      vars['primary_email'] = clientInfo.email || '';
    }
    return vars;
  } catch (error) {
    console.error('Error fetching association variables:', error);
    return {};
  }
};

export const formatLastLogin = (lastSeenAt) => {
  if (!lastSeenAt) return 'Never';
  const result = formatRelativeDateEST(lastSeenAt);
  return result === '-' ? 'Unknown' : result;
};

export const replaceVariables = (content, variables) => {
  if (!content || typeof content !== 'string') return content || '';
  if (!variables || typeof variables !== 'object') return content;
  try {
    let processed = content;
    Object.keys(variables).forEach(key => {
      const safeKey = key.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
      const regex = new RegExp(`{{\\s*${safeKey}\\s*}}|{\\s*${safeKey}\\s*}`, 'gi');
      const value = variables[key];
      const replacement = (value !== null && value !== undefined) ? String(value) : '';
      processed = processed.replace(regex, replacement);
    });
    return processed;
  } catch (error) {
    console.error('Error replacing variables in content:', error);
    return content;
  }
};

export const verifyRpcAccess = async () => {
  try {
    const dummyId = '00000000-0000-0000-0000-000000000000';
    const { data, error } = await supabase.rpc('access_shared_folder', { lookup_token: dummyId, password_attempt: 'test' });
    if (error) {
      console.error('RPC Verification Failed:', error);
      return { accessible: false, error };
    }
    return { accessible: true, data };
  } catch (err) {
    console.error('RPC Verification Exception:', err);
    return { accessible: false, error: err };
  }
};

export const decodeHtmlEntities = (text) => {
  if (!text || typeof text !== 'string') return text || '';
  try {
    const textArea = document.createElement('textarea');
    textArea.innerHTML = text;
    return textArea.value;
  } catch (e) {
    console.error('Error decoding HTML entities:', e);
    return text;
  }
};

export const clearAuthTokens = () => {
  try {
    if (typeof window === 'undefined') return;
    const storages = [localStorage, sessionStorage];
    storages.forEach(storage => {
      const keysToRemove = [];
      for (let i = 0; i < storage.length; i++) {
        const key = storage.key(i);
        if (key && (key.startsWith('sb-') || key.includes('supabase') || key.includes('auth'))) {
          keysToRemove.push(key);
        }
      }
      keysToRemove.forEach(k => storage.removeItem(k));
    });
  } catch (e) {
    console.error('[Auth Utils] Error clearing tokens:', e);
  }
};

export const getAuthTokenData = () => {
  if (typeof window === 'undefined') return null;
  try {
    for (let i = 0; i < localStorage.length; i++) {
      const key = localStorage.key(i);
      if (key && key.startsWith('sb-') && key.endsWith('-auth-token')) {
        const item = JSON.parse(localStorage.getItem(key));
        if (item && typeof item === 'object') {
          return item;
        }
      }
    }
  } catch (e) {
    console.warn('[Auth Utils] Failed to parse local auth token:', e);
  }
  return null;
};

export const validateTokenFormat = (tokenData) => {
  if (!tokenData) return false;
  const hasAccessToken = typeof tokenData.access_token === 'string' && tokenData.access_token.split('.').length === 3;
  const hasRefreshToken = typeof tokenData.refresh_token === 'string' && tokenData.refresh_token.length > 0;
  return hasAccessToken && hasRefreshToken;
};

export const isTokenExpired = (tokenData) => {
  if (!tokenData || !tokenData.expires_at) return true;
  try {
    const expiresAt = tokenData.expires_at * 1000;
    const now = Date.now();
    return (now + 10000) >= expiresAt;
  } catch (e) {
    console.error('[Auth Utils] Error checking token expiration:', e);
    return true;
  }
};
