import { NativeModules, Platform } from 'react-native';

const ANDROID_OS_NAME = 'android';

export type GoParams = {
  clientKey: string;
  firstName?: string;
  lastName?: string;
  email?: string;
  phoneNumber?: string;
  externalId: string;
  companyName: string;
};

export type PngmeDialogStyle = {
  primaryColor?: string;
  backgroundColor?: string;
  textColor?: string;
  buttonBackgroundColor?: string;
  buttonTextColor?: string;
  titleTextSize?: number;
  bodyTextSize?: number;
  buttonTextSize?: number;
  customTitle?: string;
  customSmsDescription?: string;
  customPrivacyDescription?: string;
  customButtonText?: string;
  buttonCornerRadius?: number;
  buttonElevation?: number;
  privacyPolicyUrl?: string;
  eulaUrl?: string;
};

export type PngmeError = {
  code: string;
  message: string;
};

// Response constants
const SDK_FLOW_ERROR = 'E_ON_SDK';
const SDK_IOS_INCOMPATIBLE = 'E_IOS_IS_NOT_COMPATIBLE';
const SDK_SUCCESS = 'success';
const E_INVALID_PARAMS = 'E_INVALID_PARAMS';
const E_ACTIVITY_DOES_NOT_EXIST = 'E_ACTIVITY_DOES_NOT_EXIST';

/**
 * Validate required parameters before calling SDK
 */
function validateParams(params: GoParams): PngmeError | null {
  if (!params.clientKey || params.clientKey.trim() === '') {
    return { code: E_INVALID_PARAMS, message: 'ClientKey is required' };
  }
  
  if (!params.externalId || params.externalId.trim() === '') {
    return { code: E_INVALID_PARAMS, message: 'ExternalId is required' };
  }
  
  if (!params.companyName || params.companyName.trim() === '') {
    return { code: E_INVALID_PARAMS, message: 'CompanyName is required' };
  }
  
  // Validate client key format (adjust as needed)
  if (params.clientKey.length < 32) {
    return { code: E_INVALID_PARAMS, message: 'ClientKey appears to be invalid (too short)' };
  }
  
  return null;
}

/**
 * Simple status handling - the SDK only returns success or error codes
 */
function handleSDKResponse(status: string, errorMessage?: string): string {
  if (status === SDK_SUCCESS) {
    return status;
  }
  
  // For any non-success status, throw an error with descriptive message
  const errorMsg = errorMessage || 'Unknown error occurred';
  switch (status) {
    case E_INVALID_PARAMS:
      throw new Error(`Invalid Parameters: ${errorMsg}`);
    case E_ACTIVITY_DOES_NOT_EXIST:
      throw new Error('Activity Error: No valid Android activity found. Make sure you\'re calling this from a valid React Native screen.');
    case SDK_IOS_INCOMPATIBLE:
      throw new Error('Platform Error: This SDK is only compatible with Android devices.');
    default:
      throw new Error(`SDK Error: ${errorMsg}`);
  }
}

/**
 * Basic SDK integration - shows default Pngme dialog
 */
export async function go(params: GoParams): Promise<string> {
  // Validate parameters first
  const validationError = validateParams(params);
  if (validationError) {
    throw new Error(validationError.message);
  }

  if (Platform.OS !== ANDROID_OS_NAME) {
    throw new Error('Platform Error: This SDK is only compatible with Android devices.');
  }

  return new Promise<string>((resolve, reject) => {
    try {
      const { SDKWrapper } = NativeModules;
      
      if (!SDKWrapper) {
        reject(new Error('SDK Error: SDKWrapper module not found. Make sure the native module is properly linked.'));
        return;
      }

      console.log('Calling Pngme SDK with params:', JSON.stringify(params, null, 2));
      
      SDKWrapper.go(params, (status: string, errorMessage?: string) => {
        console.log('Pngme SDK Response:', { status, errorMessage });
        
        try {
          const result = handleSDKResponse(status, errorMessage);
          resolve(result);
        } catch (error) {
          reject(error);
        }
      });
    } catch (error) {
      console.error('Error calling Pngme SDK:', error);
      reject(new Error(`SDK Error: ${error instanceof Error ? error.message : 'Unknown error occurred'}`));
    }
  });
}

/**
 * Backward compatibility - maps to standard go() method
 * @deprecated Use go() or goWithStyle() instead
 */
export async function goWithCustomDialog(params: GoParams): Promise<string> {
  console.warn('goWithCustomDialog is deprecated. Use go() or goWithStyle() instead.');
  return go(params);
}

/**
 * SDK integration with custom dialog styling
 */
export async function goWithStyle(params: GoParams, style: PngmeDialogStyle): Promise<string> {
  // Validate parameters first
  const validationError = validateParams(params);
  if (validationError) {
    throw new Error(validationError.message);
  }

  if (Platform.OS !== ANDROID_OS_NAME) {
    throw new Error('Platform Error: This SDK is only compatible with Android devices.');
  }

  return new Promise<string>((resolve, reject) => {
    try {
      const { SDKWrapper } = NativeModules;
      
      if (!SDKWrapper) {
        reject(new Error('SDK Error: SDKWrapper module not found. Make sure the native module is properly linked.'));
        return;
      }

      console.log('Calling Pngme SDK with style:', JSON.stringify({ params, style }, null, 2));
      
      SDKWrapper.goWithStyle(params, style, (status: string, errorMessage?: string) => {
        console.log('Pngme SDK with Style Response:', { status, errorMessage });
        
        try {
          const result = handleSDKResponse(status, errorMessage);
          resolve(result);
        } catch (error) {
          reject(error);
        }
      });
    } catch (error) {
      console.error('Error calling Pngme SDK with style:', error);
      reject(new Error(`SDK Error: ${error instanceof Error ? error.message : 'Unknown error occurred'}`));
    }
  });
}

/**
 * Set a default style for all SDK dialogs
 */
export function setDefaultStyle(style: PngmeDialogStyle): void {
  if (Platform.OS === ANDROID_OS_NAME) {
    try {
      const { SDKWrapper } = NativeModules;
      if (SDKWrapper) {
        SDKWrapper.setDefaultStyle(style);
        console.log('Default style set successfully');
      } else {
        console.warn('SDKWrapper module not found');
      }
    } catch (error) {
      console.warn('Error setting default style:', error);
    }
  }
}

/**
 * Clear the default style and revert to original Pngme styling
 */
export function clearDefaultStyle(): void {
  if (Platform.OS === ANDROID_OS_NAME) {
    try {
      const { SDKWrapper } = NativeModules;
      if (SDKWrapper) {
        SDKWrapper.clearDefaultStyle();
        console.log('Default style cleared successfully');
      } else {
        console.warn('SDKWrapper module not found');
      }
    } catch (error) {
      console.warn('Error clearing default style:', error);
    }
  }
}

/**
 * Check if SMS permissions are granted
 */
export async function isPermissionGranted(): Promise<boolean> {
  if (Platform.OS !== ANDROID_OS_NAME) {
    return false;
  }

  try {
    const { SDKWrapper } = NativeModules;
    if (!SDKWrapper) {
      console.warn('SDKWrapper module not found');
      return false;
    }
    
    return await SDKWrapper.isPermissionGranted();
  } catch (error) {
    console.warn('Error on PngmeSDK - isPermissionGranted', error);
    return false;
  }
}

/**
 * Get the current user's UUID
 */
export async function getUserUuid(): Promise<string | null> {
  if (Platform.OS !== ANDROID_OS_NAME) {
    return null;
  }

  try {
    const { SDKWrapper } = NativeModules;
    if (!SDKWrapper) {
      console.warn('SDKWrapper module not found');
      return null;
    }
    
    return await SDKWrapper.getUserUuid();
  } catch (error) {
    console.warn('Error on PngmeSDK - getUserUuid', error);
    return null;
  }
}

/**
 * Enhanced SDK call with pre-flight checks
 */
export async function goWithPreflightChecks(params: GoParams, style?: PngmeDialogStyle): Promise<string> {
  console.log('Starting Pngme SDK with preflight checks...');
    
  // 2. Check permissions
  const hasPermissions = await isPermissionGranted();
  console.log(`SMS permissions granted: ${hasPermissions}`);
  
  // 3. Call appropriate SDK method
  if (style) {
    return goWithStyle(params, style);
  } else {
    return go(params);
  }
}

// Export response constants for client use
export const PNGME_RESPONSES = {
  SUCCESS: SDK_SUCCESS,
  ERROR: SDK_FLOW_ERROR,
  IOS_INCOMPATIBLE: SDK_IOS_INCOMPATIBLE,
  INVALID_PARAMS: E_INVALID_PARAMS,
  ACTIVITY_DOES_NOT_EXIST: E_ACTIVITY_DOES_NOT_EXIST,
} as const;