import { createMember, handleNocoDbError } from '~/server/utils/nocodb';
import { createSessionManager } from '~/server/utils/session';
import type { Member, MembershipStatus } from '~/utils/types';

export default defineEventHandler(async (event) => {
  console.log('[api/members.post] =========================');
  console.log('[api/members.post] POST /api/members - Create new member');
  console.log('[api/members.post] Request from:', getClientIP(event));
  
  try {
    // Validate session and require Board+ privileges
    const sessionManager = createSessionManager();
    const cookieHeader = getCookie(event, 'monacousa-session') ? getHeader(event, 'cookie') : undefined;
    const session = sessionManager.getSession(cookieHeader);
    
    if (!session?.user) {
      throw createError({
        statusCode: 401,
        statusMessage: 'Authentication required'
      });
    }

    const userTier = session.user.tier;
    if (userTier !== 'board' && userTier !== 'admin') {
      throw createError({
        statusCode: 403,
        statusMessage: 'Board member privileges required to create members'
      });
    }

    console.log('[api/members.post] Authorized user:', session.user.email, 'Tier:', userTier);

    // Get and validate request body
    const body = await readBody(event);
    console.log('[api/members.post] Request body fields:', Object.keys(body));
    console.log('[api/members.post] Raw body data:', JSON.stringify(body, null, 2));

    // Map display names to snake_case field names (fallback for client issues)
    const normalizedBody = normalizeFieldNames(body);
    console.log('[api/members.post] Normalized fields:', Object.keys(normalizedBody));

    // Validate required fields
    const validationErrors = validateMemberData(normalizedBody);
    if (validationErrors.length > 0) {
      console.error('[api/members.post] Validation errors:', validationErrors);
      throw createError({
        statusCode: 400,
        statusMessage: `Validation failed: ${validationErrors.join(', ')}`
      });
    }

    // Sanitize and prepare data
    const memberData = sanitizeMemberData(normalizedBody);
    console.log('[api/members.post] Sanitized data fields:', Object.keys(memberData));

    // Create member in NocoDB
    const newMember = await createMember(memberData);

    console.log('[api/members.post] ✅ Member created successfully with ID:', newMember.Id);

    // Return processed member
    const processedMember = {
      ...newMember,
      FullName: `${newMember.first_name || ''} ${newMember.last_name || ''}`.trim(),
      FormattedPhone: formatPhoneNumber(newMember.phone)
    };

    return {
      success: true,
      data: processedMember,
      message: 'Member created successfully'
    };

  } catch (error: any) {
    console.error('[api/members.post] ❌ Error creating member:', error);
    handleNocoDbError(error, 'createMember', 'Member');
  }
});

function validateMemberData(data: any): string[] {
  const errors: string[] = [];

  // Required fields
  if (!data.first_name || typeof data.first_name !== 'string' || data.first_name.trim().length < 2) {
    errors.push('First Name is required and must be at least 2 characters');
  }

  if (!data.last_name || typeof data.last_name !== 'string' || data.last_name.trim().length < 2) {
    errors.push('Last Name is required and must be at least 2 characters');
  }

  if (!data.email || typeof data.email !== 'string' || !isValidEmail(data.email)) {
    errors.push('Valid email address is required');
  }

  // Optional field validation
  if (data.phone && typeof data.phone === 'string' && data.phone.trim()) {
    const phoneRegex = /^[\+]?[1-9][\d]{0,15}$/;
    const cleanPhone = data.phone.replace(/\D/g, '');
    if (!phoneRegex.test(cleanPhone)) {
      errors.push('Phone number format is invalid');
    }
  }

  if (data.membership_status && !['Active', 'Inactive', 'Pending', 'Expired'].includes(data.membership_status)) {
    errors.push('Invalid membership status');
  }

  return errors;
}

function sanitizeMemberData(data: any): Partial<Member> {
  const sanitized: any = {};

  // Required fields
  sanitized.first_name = data.first_name.trim();
  sanitized.last_name = data.last_name.trim();
  sanitized.email = data.email.trim().toLowerCase();

  // Optional fields
  if (data.phone) sanitized.phone = data.phone.trim();
  if (data.nationality) sanitized.nationality = data.nationality.trim();
  if (data.address) sanitized.address = data.address.trim();
  if (data.date_of_birth) sanitized.date_of_birth = data.date_of_birth;
  if (data.member_since) sanitized.member_since = data.member_since;
  if (data.membership_date_paid) sanitized.membership_date_paid = data.membership_date_paid;
  if (data.payment_due_date) sanitized.payment_due_date = data.payment_due_date;
  
  // Boolean fields
  sanitized.current_year_dues_paid = Boolean(data.current_year_dues_paid) ? 'true' : 'false';
  
  // Enum fields
  sanitized.membership_status = data.membership_status || 'Pending';

  return sanitized;
}

function normalizeFieldNames(data: any): any {
  // Field mapping for display names to snake_case
  const fieldMap: Record<string, string> = {
    'First Name': 'first_name',
    'Last Name': 'last_name',
    'Email': 'email',
    'Phone': 'phone',
    'Date of Birth': 'date_of_birth',
    'Nationality': 'nationality',
    'Address': 'address',
    'Membership Status': 'membership_status',
    'Member Since': 'member_since',
    'Current Year Dues Paid': 'current_year_dues_paid',
    'Membership Date Paid': 'membership_date_paid',
    'Payment Due Date': 'payment_due_date'
  };

  const normalized: any = {};
  
  // Map display names to snake_case
  for (const [key, value] of Object.entries(data)) {
    const normalizedKey = fieldMap[key] || key;
    normalized[normalizedKey] = value;
  }

  console.log('[api/members.post] Field mapping applied:', {
    original: Object.keys(data),
    normalized: Object.keys(normalized)
  });

  return normalized;
}

function isValidEmail(email: string): boolean {
  const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
  return emailRegex.test(email);
}

function formatPhoneNumber(phone: string): string {
  if (!phone) return '';
  const cleaned = phone.replace(/\D/g, '');
  if (cleaned.length === 10) {
    return `(${cleaned.substring(0, 3)}) ${cleaned.substring(3, 6)}-${cleaned.substring(6)}`;
  } else if (cleaned.length === 11 && cleaned.startsWith('1')) {
    return `+1 (${cleaned.substring(1, 4)}) ${cleaned.substring(4, 7)}-${cleaned.substring(7)}`;
  }
  return phone;
}
