#!/usr/bin/env python3
"""
Анализ связей между идентифицированными компаниями
Построение графа деловых отношений между 43+ компаниями
"""
import json
from pathlib import Path
from collections import defaultdict, Counter

print("=== АНАЛИЗ СВЯЗЕЙ МЕЖДУ КОМПАНИЯМИ ===\n")

# Загрузка результатов идентификации
INPUT_FILE = Path('/root/ir-assessment/redteam/irelydata/deep_company_identification.json')
OUTPUT_FILE = Path('/root/ir-assessment/redteam/irelydata/company_relationships.json')

print(f"Загрузка данных из {INPUT_FILE.name}...")
with open(INPUT_FILE) as f:
    companies = json.load(f)

print(f"Загружено {len(companies)} компаний\n")

# Структуры для анализа связей
shared_names = defaultdict(list)  # Общие имена -> список компаний
shared_tax_ids = defaultdict(list)  # Общие Tax IDs -> список компаний
shared_emails = defaultdict(list)  # Общие email -> список компаний
shared_phones = defaultdict(list)  # Общие телефоны -> список компаний

# Анализ каждой компании
for company in companies:
    db_name = company['db_name']
    company_name = company['company_name']
    
    print(f"[{db_name}] Анализ связей...")
    
    # Анализ имен
    for name in company.get('entity_names', []):
        if name and len(name) > 3:  # Фильтр коротких имен
            shared_names[name].append({
                'db': db_name,
                'company': company_name
            })
    
    # Анализ Tax IDs
    for tax_id in company.get('tax_ids', []):
        if tax_id and len(tax_id) > 5:
            shared_tax_ids[tax_id].append({
                'db': db_name,
                'company': company_name
            })
    
    # Анализ email
    for email in company.get('emails', []):
        if email and '@' in email:
            shared_emails[email].append({
                'db': db_name,
                'company': company_name
            })
    
    # Анализ телефонов
    for phone in company.get('phone_numbers', []):
        if phone and len(phone) > 5:
            shared_phones[phone].append({
                'db': db_name,
                'company': company_name
            })

print(f"\n{'='*60}")
print("АНАЛИЗ РЕЗУЛЬТАТОВ")
print("="*60)

# Фильтрация только тех, кто встречается в 2+ компаниях
shared_names_filtered = {k: v for k, v in shared_names.items() if len(set(c['db'] for c in v)) >= 2}
shared_tax_ids_filtered = {k: v for k, v in shared_tax_ids.items() if len(set(c['db'] for c in v)) >= 2}
shared_emails_filtered = {k: v for k, v in shared_emails.items() if len(set(c['db'] for c in v)) >= 2}
shared_phones_filtered = {k: v for k, v in shared_phones.items() if len(set(c['db'] for c in v)) >= 2}

print(f"\nОбщие имена (2+ компаний): {len(shared_names_filtered)}")
print(f"Общие Tax IDs (2+ компаний): {len(shared_tax_ids_filtered)}")
print(f"Общие email (2+ компаний): {len(shared_emails_filtered)}")
print(f"Общие телефоны (2+ компаний): {len(shared_phones_filtered)}")

# Построение графа связей
print(f"\n{'='*60}")
print("ПОСТРОЕНИЕ ГРАФА СВЯЗЕЙ")
print("="*60)

company_graph = defaultdict(lambda: {
    'name': None,
    'connections': defaultdict(set),  # company -> тип связи
    'shared_entities': []
})

# Анализ общих имен
for name, entries in shared_names_filtered.items():
    unique_companies = list(set(e['company'] for e in entries if e['company']))
    if len(unique_companies) >= 2:
        for i, company1 in enumerate(unique_companies):
            for company2 in unique_companies[i+1:]:
                company_graph[company1]['connections'][company2].add('shared_name')
                company_graph[company2]['connections'][company1].add('shared_name')
                company_graph[company1]['shared_entities'].append(name)
                company_graph[company2]['shared_entities'].append(name)

# Анализ общих Tax IDs
for tax_id, entries in shared_tax_ids_filtered.items():
    unique_companies = list(set(e['company'] for e in entries if e['company']))
    if len(unique_companies) >= 2:
        for i, company1 in enumerate(unique_companies):
            for company2 in unique_companies[i+1:]:
                company_graph[company1]['connections'][company2].add('shared_tax_id')
                company_graph[company2]['connections'][company1].add('shared_tax_id')

# Анализ общих email
for email, entries in shared_emails_filtered.items():
    unique_companies = list(set(e['company'] for e in entries if e['company']))
    if len(unique_companies) >= 2:
        for i, company1 in enumerate(unique_companies):
            for company2 in unique_companies[i+1:]:
                company_graph[company1]['connections'][company2].add('shared_email')
                company_graph[company2]['connections'][company1].add('shared_email')

# Преобразование в JSON-совместимый формат
result = {
    'total_companies': len(companies),
    'shared_names_count': len(shared_names_filtered),
    'shared_tax_ids_count': len(shared_tax_ids_filtered),
    'shared_emails_count': len(shared_emails_filtered),
    'shared_phones_count': len(shared_phones_filtered),
    'companies_with_connections': len(company_graph),
    'top_shared_names': [
        {'name': name, 'companies': list(set(e['company'] for e in entries if e['company']))}
        for name, entries in sorted(shared_names_filtered.items(), 
                                    key=lambda x: len(set(e['db'] for e in x[1])), 
                                    reverse=True)[:20]
    ],
    'top_shared_tax_ids': [
        {'tax_id': tax_id, 'companies': list(set(e['company'] for e in entries if e['company']))}
        for tax_id, entries in sorted(shared_tax_ids_filtered.items(),
                                      key=lambda x: len(set(e['db'] for e in x[1])),
                                      reverse=True)[:20]
    ],
    'top_shared_emails': [
        {'email': email, 'companies': list(set(e['company'] for e in entries if e['company']))}
        for email, entries in sorted(shared_emails_filtered.items(),
                                     key=lambda x: len(set(e['db'] for e in x[1])),
                                     reverse=True)[:20]
    ],
    'company_graph': {
        company: {
            'connections': {
                conn: list(types) for conn, types in data['connections'].items()
            },
            'shared_entities': list(set(data['shared_entities']))[:20]
        }
        for company, data in company_graph.items()
    }
}

# Сохранение
print(f"\nСохранение результатов...")
with open(OUTPUT_FILE, 'w', encoding='utf-8') as f:
    json.dump(result, f, indent=2, ensure_ascii=False)

print(f"\n{'='*60}")
print("ИТОГИ АНАЛИЗА")
print("="*60)

print(f"\nВсего компаний: {len(companies)}")
print(f"Компаний со связями: {len(company_graph)}")
print(f"Общих имен: {len(shared_names_filtered)}")
print(f"Общих Tax IDs: {len(shared_tax_ids_filtered)}")
print(f"Общих email: {len(shared_emails_filtered)}")
print(f"Общих телефонов: {len(shared_phones_filtered)}")

print(f"\n{'='*60}")
print("ТОП-10 ОБЩИХ ИМЕН")
print("="*60)
for i, item in enumerate(result['top_shared_names'][:10], 1):
    print(f"\n{i}. {item['name']}")
    print(f"   Компании ({len(item['companies'])}):")
    for company in item['companies'][:5]:
        print(f"     • {company}")
    if len(item['companies']) > 5:
        print(f"     ... и еще {len(item['companies']) - 5}")

print(f"\n{'='*60}")
print("ТОП-10 ОБЩИХ TAX IDs")
print("="*60)
for i, item in enumerate(result['top_shared_tax_ids'][:10], 1):
    print(f"\n{i}. {item['tax_id']}")
    print(f"   Компании ({len(item['companies'])}):")
    for company in item['companies'][:5]:
        print(f"     • {company}")
    if len(item['companies']) > 5:
        print(f"     ... и еще {len(item['companies']) - 5}")

print(f"\n{'='*60}")
print("ТОП-10 КОМПАНИЙ ПО КОЛИЧЕСТВУ СВЯЗЕЙ")
print("="*60)
sorted_companies = sorted(
    company_graph.items(),
    key=lambda x: len(x[1]['connections']),
    reverse=True
)
for i, (company, data) in enumerate(sorted_companies[:10], 1):
    print(f"\n{i}. {company}")
    print(f"   Связей: {len(data['connections'])}")
    for conn, types in list(data['connections'].items())[:5]:
        print(f"     • {conn} ({', '.join(types)})")
    if len(data['connections']) > 5:
        print(f"     ... и еще {len(data['connections']) - 5}")

print(f"\n{'='*60}")
print(f"Результаты сохранены: {OUTPUT_FILE}")
print("="*60)
