import { Owner, Phone } from '../../types';
import { ab } from '../ab';
import { randomDelay } from '../anti-detection';

// Titles to strip from owner names
const TITLE_PATTERN = /\s+(President|CEO|Manager|Member|Director|Officer|Secretary|Treasurer|VP|Vice President|Partner|Owner|Agent|Trustee|Chairman|Principal)$/i;

/**
 * Extract owners + contact info from the Owner tab.
 * Reonomy now shows contacts directly on the Owner tab (no more View Contacts flow).
 */
export async function extractOwners(): Promise<Owner[]> {
  // Click Owner tab
  ab('find role tab click --name "Owner"');
  await randomDelay(4000, 6000);

  const snap = ab('snapshot -i');
  return parseOwnersFromSnapshot(snap.output || '');
}

/**
 * Parse owner data from a snapshot string.
 * Exported separately for testing.
 */
export function parseOwnersFromSnapshot(snapshot: string): Owner[] {
  if (!snapshot) return [];

  const owners: Owner[] = [];
  const lines = snapshot.split('\n');
  let currentOwner: Owner | null = null;

  for (const line of lines) {
    // Owner name: link "Name" [ref=eN]
    const ownerMatch = line.match(/link "([^"]+)" \[ref=e\d+\]/);
    if (ownerMatch) {
      const name = ownerMatch[1];
      // Skip navigation links and very short/long names
      if (
        name.includes('Call') || name.includes('Send') ||
        name.includes('Sign') || name.includes('Advanced') ||
        name.includes('http') || name.includes("Don't") ||
        name.length <= 2 || name.length >= 80 ||
        !/[A-Z]/.test(name)
      ) {
        continue;
      }

      // Save previous owner if it had contacts
      if (currentOwner && (currentOwner.phones.length > 0 || currentOwner.emails.length > 0)) {
        owners.push(currentOwner);
      }

      // Strip titles from name
      const cleanName = name.replace(TITLE_PATTERN, '').trim();
      currentOwner = { name: cleanName, phones: [], emails: [] };
    }

    // Phone: button "1-330-966-4686" or "718-652-3191 Residential" or "201-741-9321 Mobile"
    const phoneMatch = line.match(/button "(?:1-)?(\d{3}-\d{3}-\d{4})(?:\s+(.+))?" \[ref=e\d+\]/);
    if (phoneMatch && currentOwner) {
      const phone: Phone = {
        number: line.includes('1-') ? `1-${phoneMatch[1]}` : phoneMatch[1],
        type: phoneMatch[2] || 'Unknown',
      };
      currentOwner.phones.push(phone);
    }

    // Long phone numbers (10-14 digits, no dashes)
    const longPhoneMatch = line.match(/button "(\d{10,14})" \[ref=e\d+\]/);
    if (longPhoneMatch && currentOwner) {
      currentOwner.phones.push({ number: longPhoneMatch[1], type: 'Unknown' });
    }

    // Email: button "user@example.com" [ref=eN]
    const emailMatch = line.match(/button "([a-zA-Z0-9._%+\-]+@[a-zA-Z0-9.\-]+\.[a-zA-Z]{2,})" \[ref=e\d+\]/);
    if (emailMatch && currentOwner) {
      currentOwner.emails.push(emailMatch[1]);
    }
  }

  // Don't forget the last owner
  if (currentOwner && (currentOwner.phones.length > 0 || currentOwner.emails.length > 0)) {
    owners.push(currentOwner);
  }

  // Deduplicate owners by name, merge contacts
  return deduplicateOwners(owners);
}

function deduplicateOwners(owners: Owner[]): Owner[] {
  const seen = new Map<string, Owner>();
  const deduped: Owner[] = [];

  for (const owner of owners) {
    const key = owner.name.toLowerCase();
    if (seen.has(key)) {
      const existing = seen.get(key)!;
      for (const p of owner.phones) {
        if (!existing.phones.find((ep: { number: string }) => ep.number === p.number)) {
          existing.phones.push(p);
        }
      }
      for (const e of owner.emails) {
        if (!existing.emails.includes(e)) {
          existing.emails.push(e);
        }
      }
    } else {
      const entry = { ...owner, phones: [...owner.phones], emails: [...owner.emails] };
      seen.set(key, entry);
      deduped.push(entry);
    }
  }

  return deduped;
}
