"""
vTiger Cloud CRM Integration Service
Handles subscription and sales order data retrieval
"""
import logging
import json
import aiohttp
from typing import List, Dict, Optional
from app.core.config import settings

logger = logging.getLogger(__name__)


class VTigerService:
    """Service for integrating with vTiger Cloud CRM via REST API"""
    
    def __init__(self):
        self.base_url = getattr(settings, 'VTIGER_URL', None)
        self.username = getattr(settings, 'VTIGER_USERNAME', None)
        self.api_key = getattr(settings, 'VTIGER_API_KEY', None)
        
        # REST API endpoint
        if self.base_url:
            self.rest_endpoint = f"{self.base_url}/restapi/v1/vtiger/default"
        else:
            self.rest_endpoint = None
        
        if not all([self.base_url, self.username, self.api_key]):
            logger.warning("⚠️ vTiger credentials not fully configured")
    
    def _get_auth(self):
        """Get HTTP Basic Auth credentials"""
        if not self.api_key:
            raise ValueError("VTIGER_API_KEY not configured")
        return aiohttp.BasicAuth(self.username, self.api_key)
    
    async def query(self, query_string: str) -> List[Dict]:
        """
        Execute a query on vTiger REST API
        
        Args:
            query_string: SQL-like query (e.g., "SELECT * FROM Accounts;")
            
        Returns:
            List of records
        """
        if not self.rest_endpoint:
            raise ValueError("VTIGER_URL not configured")
        
        try:
            auth = self._get_auth()
            async with aiohttp.ClientSession() as session:
                async with session.get(
                    f"{self.rest_endpoint}/query",
                    params={"query": query_string},
                    auth=auth
                ) as response:
                    text = await response.text()
                    
                    if response.status == 200:
                        # vTiger returns text/json instead of application/json
                        import json
                        try:
                            data = json.loads(text)
                        except json.JSONDecodeError as e:
                            logger.error(f"❌ Invalid JSON in query response: {text[:200]}")
                            return []
                        
                        if data.get('success'):
                            result = data.get('result', [])
                            logger.info(f"✅ Query returned {len(result)} records")
                            return result
                        else:
                            logger.error(f"❌ vTiger query failed: {data.get('error')}")
                            return []
                    else:
                        logger.error(f"❌ vTiger query HTTP error {response.status}")
                        logger.error(f"Query: {query_string}")
                        logger.error(f"Response: {text[:500]}")
                        return []
        except Exception as e:
            logger.error(f"❌ vTiger query error: {e}")
            return []
    
    async def get_customer_sales_orders(self, vtiger_account_id: str) -> List[Dict]:
        """
        Fetch sales orders for a customer from vTiger
        
        Args:
            vtiger_account_id: vTiger account ID (e.g., "3x760")
            
        Returns:
            List of sales order records
        """
        if not vtiger_account_id:
            logger.warning("⚠️ No vTiger account ID provided")
            return []
        
        try:
            # Query for sales orders linked to this account
            query = f"SELECT * FROM SalesOrder WHERE account_id='{vtiger_account_id}';"
            
            logger.info(f"🔍 Fetching sales orders for vTiger account {vtiger_account_id}")
            orders = await self.query(query)
            
            logger.info(f"✅ Found {len(orders)} sales orders")
            return orders
            
        except Exception as e:
            logger.error(f"❌ Error fetching sales orders: {e}")
            return []
    
    async def get_customer_subscriptions(self, vtiger_account_id: str) -> List[Dict]:
        """
        Fetch subscriptions for a customer from vTiger
        
        Args:
            vtiger_account_id: vTiger account ID (e.g., "3x760")
            
        Returns:
            List of subscription records
        """
        if not vtiger_account_id:
            logger.warning("⚠️ No vTiger account ID provided")
            return []
        
        try:
            # Query for subscriptions linked to this account (note: module name is singular "Subscription")
            query = f"SELECT * FROM Subscription WHERE account_id='{vtiger_account_id}';"
            
            logger.info(f"🔍 Fetching subscriptions for vTiger account {vtiger_account_id}")
            subscriptions = await self.query(query)
            
            logger.info(f"✅ Found {len(subscriptions)} subscriptions")
            return subscriptions
            
        except Exception as e:
            logger.error(f"❌ Error fetching subscriptions: {e}")
            return []
    
    async def get_subscription(self, subscription_id: str) -> Optional[Dict]:
        """
        Fetch full subscription details with LineItems from vTiger
        
        Args:
            subscription_id: vTiger subscription ID (e.g., "72x123")
            
        Returns:
            Subscription record with LineItems array or None
        """
        if not self.rest_endpoint:
            raise ValueError("VTIGER_URL not configured")
        
        try:
            auth = self._get_auth()
            
            async with aiohttp.ClientSession() as session:
                url = f"{self.rest_endpoint}/retrieve?id={subscription_id}"
                
                async with session.get(url, auth=auth) as response:
                    if response.status == 200:
                        text = await response.text()
                        data = json.loads(text)
                        if data.get('success'):
                            logger.info(f"✅ Retrieved subscription {subscription_id}")
                            return data.get('result')
                        else:
                            logger.error(f"❌ vTiger API error: {data.get('error')}")
                            return None
                    else:
                        logger.error(f"❌ HTTP {response.status} retrieving subscription")
                        return None
                        
        except Exception as e:
            logger.error(f"❌ Error retrieving subscription: {e}")
            return None
    
    async def get_account(self, vtiger_account_id: str) -> Optional[Dict]:
        """
        Fetch account details from vTiger
        
        Args:
            vtiger_account_id: vTiger account ID (e.g., "3x760")
            
        Returns:
            Account record with BMC Låst field (cf_accounts_bmclst) or None
        """
        if not vtiger_account_id:
            logger.warning("⚠️ No vTiger account ID provided")
            return None
        
        try:
            # Query for account by ID
            query = f"SELECT * FROM Accounts WHERE id='{vtiger_account_id}';"
            
            logger.info(f"🔍 Fetching account details for {vtiger_account_id}")
            accounts = await self.query(query)
            
            if accounts:
                logger.info(f"✅ Found account: {accounts[0].get('accountname', 'Unknown')}")
                return accounts[0]
            else:
                logger.warning(f"⚠️ No account found with ID {vtiger_account_id}")
                return None
            
        except Exception as e:
            logger.error(f"❌ Error fetching account: {e}")
            return None
    
    async def test_connection(self) -> bool:
        """
        Test vTiger connection using /me endpoint
        
        Returns:
            True if connection successful
        """
        if not self.rest_endpoint:
            raise ValueError("VTIGER_URL not configured in .env")
        
        try:
            auth = self._get_auth()
            logger.info(f"🔑 Testing vTiger connection...")
            
            async with aiohttp.ClientSession() as session:
                async with session.get(
                    f"{self.rest_endpoint}/me",
                    auth=auth
                ) as response:
                    if response.status == 200:
                        # vTiger returns text/json instead of application/json
                        text = await response.text()
                        import json
                        data = json.loads(text)
                        
                        if data.get('success'):
                            user_name = data['result'].get('user_name')
                            logger.info(f"✅ vTiger connection successful (user: {user_name})")
                            return True
                        else:
                            logger.error(f"❌ vTiger API returned success=false: {data}")
                            return False
                    else:
                        error_text = await response.text()
                        logger.error(f"❌ vTiger connection failed: HTTP {response.status}: {error_text}")
                        return False
                        
        except Exception as e:
            logger.error(f"❌ vTiger connection error: {e}")
            return False
    
    async def create_subscription(
        self,
        account_id: str,
        subject: str,
        startdate: str,
        generateinvoiceevery: str,
        subscriptionstatus: str = "Active",
        enddate: Optional[str] = None,
        products: Optional[List[Dict]] = None
    ) -> Dict:
        """
        Create a new subscription in vTiger
        
        Args:
            account_id: vTiger account ID (e.g., "3x123")
            subject: Subscription subject/name
            startdate: Start date (YYYY-MM-DD)
            generateinvoiceevery: Frequency ("Monthly", "Quarterly", "Yearly")
            subscriptionstatus: Status ("Active", "Cancelled", "Stopped")
            enddate: End date (YYYY-MM-DD), optional
            products: List of products [{"productid": "id", "quantity": 1, "listprice": 100}]
        """
        if not self.rest_endpoint:
            raise ValueError("VTIGER_URL not configured")
        
        try:
            auth = self._get_auth()
            
            # Build subscription data
            subscription_data = {
                "account_id": account_id,
                "subject": subject,
                "startdate": startdate,
                "generateinvoiceevery": generateinvoiceevery,
                "subscriptionstatus": subscriptionstatus,
            }
            
            if enddate:
                subscription_data["enddate"] = enddate
            
            # Add products if provided
            if products:
                subscription_data["products"] = products
            
            async with aiohttp.ClientSession() as session:
                create_url = f"{self.rest_endpoint}/create"
                
                payload = {
                    "elementType": "Subscription",
                    "element": subscription_data
                }
                
                logger.info(f"📤 Creating subscription: {subject}")
                
                async with session.post(create_url, json=payload, auth=auth) as response:
                    if response.status == 200:
                        data = await response.json()
                        if data.get("success"):
                            result = data.get("result", {})
                            logger.info(f"✅ Created subscription: {result.get('id')}")
                            return result
                        else:
                            error_msg = data.get("error", {}).get("message", "Unknown error")
                            raise Exception(f"vTiger API error: {error_msg}")
                    else:
                        error_text = await response.text()
                        raise Exception(f"HTTP {response.status}: {error_text}")
                        
        except Exception as e:
            logger.error(f"❌ Error creating subscription: {e}")
            raise
    
    async def update_subscription(self, subscription_id: str, updates: Dict, line_items: List[Dict] = None) -> Dict:
        """
        Update a subscription in vTiger with optional line item price updates
        
        Args:
            subscription_id: vTiger subscription ID (e.g., "72x123")
            updates: Dictionary of fields to update (subject, startdate, etc.)
            line_items: Optional list of line items with updated prices
                       Each item: {"productid": "6x123", "quantity": "3", "listprice": "299.00"}
        """
        if not self.rest_endpoint:
            raise ValueError("VTIGER_URL not configured")
        
        try:
            auth = self._get_auth()
            
            async with aiohttp.ClientSession() as session:
                # For custom fields (cf_*), we need to retrieve first for context
                if any(k.startswith('cf_') for k in updates.keys()):
                    logger.info(f"📥 Retrieving subscription {subscription_id} for custom field update")
                    current_sub = await self.get_subscription(subscription_id)
                    if current_sub:
                        # Only include essential fields + custom field update
                        essential_fields = ['id', 'account_id', 'subject', 'startdate', 
                                          'generateinvoiceevery', 'subscriptionstatus']
                        element_data = {
                            k: current_sub[k] 
                            for k in essential_fields 
                            if k in current_sub
                        }
                        element_data.update(updates)
                        element_data['id'] = subscription_id
                    else:
                        element_data = {"id": subscription_id, **updates}
                else:
                    element_data = {"id": subscription_id, **updates}
                
                update_url = f"{self.rest_endpoint}/update"
                
                # Add LineItems if provided
                if line_items:
                    element_data["LineItems"] = line_items
                    logger.info(f"📝 Updating {len(line_items)} line items")
                
                payload = {
                    "elementType": "Subscription",
                    "element": element_data
                }
                
                logger.info(f"📤 Updating subscription {subscription_id}: {list(updates.keys())}")
                logger.debug(f"Payload: {json.dumps(payload, indent=2)}")
                
                async with session.post(update_url, json=payload, auth=auth) as response:
                    if response.status == 200:
                        text = await response.text()
                        data = json.loads(text)
                        if data.get("success"):
                            result = data.get("result", {})
                            logger.info(f"✅ Updated subscription: {subscription_id}")
                            return result
                        else:
                            error_msg = data.get("error", {}).get("message", "Unknown error")
                            logger.error(f"❌ vTiger error response: {data.get('error')}")
                            raise Exception(f"vTiger API error: {error_msg}")
                    else:
                        error_text = await response.text()
                        logger.error(f"❌ vTiger HTTP error: {error_text[:500]}")
                        raise Exception(f"HTTP {response.status}: {error_text}")
                        
        except Exception as e:
            logger.error(f"❌ Error updating subscription: {e}")
            raise


# Singleton instance
_vtiger_service = None

def get_vtiger_service() -> VTigerService:
    """Get or create vTiger service singleton"""
    global _vtiger_service
    if _vtiger_service is None:
        _vtiger_service = VTigerService()
    return _vtiger_service
