#!/usr/bin/env python3
"""
Relink Hub Customers to e-conomic Customer Numbers
===================================================

Dette script matcher Hub kunder med e-conomic kunder baseret på NAVN matching
og opdaterer economic_customer_number feltet.

VIGTIG: Dette script ændrer IKKE data i e-conomic - det opdaterer kun Hub's links.

Usage:
    python scripts/relink_economic_customers.py [--dry-run] [--force]
    
Options:
    --dry-run    Vis hvad der ville blive ændret uden at gemme
    --force      Overskriv eksisterende links (standard: skip hvis allerede linket)
    
Note: Matcher på kundenavn (case-insensitive, fjerner mellemrum/punktum)
"""

import sys
import asyncio
import logging
from typing import Dict, List, Optional
import argparse

import aiohttp

sys.path.insert(0, '/app')

from app.core.config import settings
from app.core.database import execute_query, execute_update, init_db

logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)


class EconomicRelinkService:
    """Service til at relinke Hub kunder til e-conomic"""
    
    def __init__(self, dry_run: bool = False, force: bool = False):
        self.api_url = settings.ECONOMIC_API_URL
        self.app_secret_token = settings.ECONOMIC_APP_SECRET_TOKEN
        self.agreement_grant_token = settings.ECONOMIC_AGREEMENT_GRANT_TOKEN
        self.dry_run = dry_run
        self.force = force
        
        if dry_run:
            logger.info("🔍 DRY RUN MODE - ingen ændringer gemmes")
        if force:
            logger.info("⚠️  FORCE MODE - overskriver eksisterende links")
    
    async def fetch_economic_customers(self) -> List[Dict]:
        """Hent alle kunder fra e-conomic API"""
        logger.info("📥 Henter kunder fra e-conomic...")
        
        headers = {
            'X-AppSecretToken': self.app_secret_token,
            'X-AgreementGrantToken': self.agreement_grant_token,
            'Content-Type': 'application/json'
        }
        
        all_customers = []
        page = 0
        page_size = 1000
        
        async with aiohttp.ClientSession() as session:
            while True:
                url = f"{self.api_url}/customers?skippages={page}&pagesize={page_size}"
                
                try:
                    async with session.get(url, headers=headers) as response:
                        if response.status != 200:
                            error_text = await response.text()
                            logger.error(f"❌ e-conomic API fejl: {response.status} - {error_text}")
                            break
                        
                        data = await response.json()
                        customers = data.get('collection', [])
                        
                        if not customers:
                            break
                        
                        all_customers.extend(customers)
                        logger.info(f"  Hentet side {page + 1}: {len(customers)} kunder")
                        
                        if len(customers) < page_size:
                            break
                        
                        page += 1
                        
                except Exception as e:
                    logger.error(f"❌ Fejl ved hentning fra e-conomic: {e}")
                    break
        
        logger.info(f"✅ Hentet {len(all_customers)} kunder fra e-conomic")
        return all_customers
    
    def get_hub_customers(self) -> List[Dict]:
        """Hent alle Hub kunder"""
        logger.info("📥 Henter kunder fra Hub database...")
        
        query = """
            SELECT id, name, cvr_number, economic_customer_number
            FROM customers
            WHERE name IS NOT NULL AND name != ''
            ORDER BY name
        """
        
        customers = execute_query(query)
        logger.info(f"✅ Hentet {len(customers)} Hub kunder")
        
        return customers
    
    def normalize_name(self, name: str) -> str:
        """Normaliser kundenavn for matching"""
        if not name:
            return ""
        # Lowercase, fjern punktum, mellemrum, A/S, ApS osv
        name = name.lower()
        name = name.replace('a/s', '').replace('aps', '').replace('i/s', '')
        name = name.replace('.', '').replace(',', '').replace('-', '')
        name = ''.join(name.split())  # Fjern alle mellemrum
        return name
    
    def build_name_mapping(self, economic_customers: List[Dict]) -> Dict[str, int]:
        """
        Byg mapping fra normaliseret kundenavn til e-conomic customerNumber.
        """
        name_map = {}
        
        for customer in economic_customers:
            customer_number = customer.get('customerNumber')
            customer_name = customer.get('name', '').strip()
            
            if not customer_number or not customer_name:
                continue
            
            normalized = self.normalize_name(customer_name)
            
            if normalized:
                if normalized in name_map:
                    logger.warning(f"⚠️  Duplikat navn '{customer_name}' i e-conomic (kunde {customer_number} og {name_map[normalized]})")
                else:
                    name_map[normalized] = customer_number
        
        logger.info(f"✅ Bygget navn mapping med {len(name_map)} unikke navne")
        return name_map
    
    async def relink_customers(self):
        """Hovedfunktion - relink alle kunder"""
        logger.info("🚀 Starter relink proces...")
        logger.info("=" * 60)
        
        # Hent data
        economic_customers = await self.fetch_economic_customers()
        if not economic_customers:
            logger.error("❌ Kunne ikke hente e-conomic kunder - afbryder")
            return
        
        hub_customers = self.get_hub_customers()
        if not hub_customers:
            logger.warning("⚠️  Ingen Hub kunder fundet")
            return
        
        # Byg navn mapping
        name_map = self.build_name_mapping(economic_customers)
        
        # Match og opdater
        logger.info("")
        logger.info("🔗 Matcher og opdaterer links...")
        logger.info("=" * 60)
        
        stats = {
            'matched': 0,
            'updated': 0,
            'skipped_already_linked': 0,
            'skipped_no_match': 0,
            'errors': 0
        }
        
        for hub_customer in hub_customers:
            hub_id = hub_customer['id']
            hub_name = hub_customer['name']
            current_economic_number = hub_customer.get('economic_customer_number')
            
            # Normaliser navn og find match
            normalized_name = self.normalize_name(hub_name)
            
            if not normalized_name:
                continue
            
            # Find match i e-conomic
            economic_number = name_map.get(normalized_name)
            
            if not economic_number:
                stats['skipped_no_match'] += 1
                logger.debug(f"  ⏭️  {hub_name} - ingen match i e-conomic")
                continue
            
            stats['matched'] += 1
            
            # Check om allerede linket
            if current_economic_number and not self.force:
                if current_economic_number == economic_number:
                    stats['skipped_already_linked'] += 1
                    logger.debug(f"  ✓ {hub_name} allerede linket til {economic_number}")
                else:
                    stats['skipped_already_linked'] += 1
                    logger.warning(f"  ⚠️  {hub_name} allerede linket til {current_economic_number} (ville være {economic_number}) - brug --force")
                continue
            
            # Opdater link
            if self.dry_run:
                logger.info(f"  🔍 {hub_name} → e-conomic kunde {economic_number}")
                stats['updated'] += 1
            else:
                try:
                    execute_update(
                        "UPDATE customers SET economic_customer_number = %s WHERE id = %s",
                        (economic_number, hub_id)
                    )
                    logger.info(f"  ✅ {hub_name} → e-conomic kunde {economic_number}")
                    stats['updated'] += 1
                except Exception as e:
                    logger.error(f"  ❌ Fejl ved opdatering af {hub_name}: {e}")
                    stats['errors'] += 1
        
        # Vis statistik
        logger.info("")
        logger.info("=" * 60)
        logger.info("📊 RESULTAT:")
        logger.info(f"  Kunder matchet:           {stats['matched']}")
        logger.info(f"  Links opdateret:          {stats['updated']}")
        logger.info(f"  Allerede linket (skipped): {stats['skipped_already_linked']}")
        logger.info(f"  Ingen match i e-conomic:  {stats['skipped_no_match']}")
        logger.info(f"  Fejl:                     {stats['errors']}")
        logger.info("=" * 60)
        
        if self.dry_run:
            logger.info("🔍 DRY RUN - ingen ændringer blev gemt")
            logger.info("   Kør uden --dry-run for at gemme ændringer")


async def main():
    parser = argparse.ArgumentParser(
        description='Relink Hub kunder til e-conomic baseret på CVR-nummer'
    )
    parser.add_argument(
        '--dry-run',
        action='store_true',
        help='Vis hvad der ville blive ændret uden at gemme'
    )
    parser.add_argument(
        '--force',
        action='store_true',
        help='Overskriv eksisterende links'
    )
    
    args = parser.parse_args()
    
    # Initialize database connection
    init_db()
    
    service = EconomicRelinkService(dry_run=args.dry_run, force=args.force)
    await service.relink_customers()


if __name__ == '__main__':
    asyncio.run(main())
