"""
Namecheap Domain Reseller API wrapper.
Docs: https://www.namecheap.com/support/api/intro/
Set NAMECHEAP_SANDBOX=True for testing (sandbox.namecheap.com).
"""
import requests
import xml.etree.ElementTree as ET
from django.conf import settings


def _api_url():
    if getattr(settings, 'NAMECHEAP_SANDBOX', True):
        return 'https://api.sandbox.namecheap.com/xml.response'
    return 'https://api.namecheap.com/xml.response'


def _base_params():
    return {
        'ApiUser':   settings.NAMECHEAP_API_USER,
        'ApiKey':    settings.NAMECHEAP_API_KEY,
        'UserName':  settings.NAMECHEAP_USERNAME,
        'ClientIp':  settings.NAMECHEAP_CLIENT_IP,
    }


def _call(command, extra_params=None):
    """Make an API call, return parsed XML root or raise."""
    params = _base_params()
    params['Command'] = command
    if extra_params:
        params.update(extra_params)
    resp = requests.get(_api_url(), params=params, timeout=30)
    resp.raise_for_status()
    root = ET.fromstring(resp.content)
    status = root.attrib.get('Status', 'ERROR')
    if status == 'ERROR':
        errors = root.findall('.//{http://api.namecheap.com/xml.response}Error')
        msg = '; '.join(e.text or '' for e in errors) if errors else 'Unknown Namecheap API error'
        raise Exception(f'Namecheap API error: {msg}')
    return root


def check_availability(domains):
    """
    Check availability of one or more domain names.
    `domains` — list of full domain names, e.g. ['mybusiness.co.uk', 'mybusiness.com']
    Returns dict: {domain_name: True/False}
    """
    root = _call('namecheap.domains.check', {'DomainList': ','.join(domains)})
    ns = 'http://api.namecheap.com/xml.response'
    results = {}
    for el in root.findall(f'.//{{{ns}}}DomainCheckResult'):
        name = el.attrib.get('Domain', '')
        avail = el.attrib.get('Available', 'false').lower() == 'true'
        results[name] = avail
    return results


def get_tld_prices():
    """
    Fetch pricing for all TLDs the reseller account supports.
    Returns list of dicts: [{tld, register_price, renew_price, transfer_price}]
    """
    root = _call('namecheap.users.getPricing', {
        'ProductType': 'DOMAIN',
        'ActionName': 'REGISTER',
    })
    ns = 'http://api.namecheap.com/xml.response'
    prices = []
    for product in root.findall(f'.//{{{ns}}}Product'):
        tld = product.attrib.get('Name', '')
        for price_el in product.findall(f'{{{ns}}}Price'):
            if price_el.attrib.get('Duration') == '1':
                prices.append({
                    'tld': f'.{tld}',
                    'register_price': float(price_el.attrib.get('YourPrice', 0)),
                    'renew_price': float(price_el.attrib.get('YourRenewalPrice', 0)),
                })
                break
    return prices


def register_domain(domain_name, years, registrant_info):
    """
    Register a domain name.
    `domain_name` — full domain e.g. 'mybusiness.co.uk'
    `years` — int, registration period
    `registrant_info` — dict with keys:
        FirstName, LastName, Address1, City, StateProvince, PostalCode,
        Country, Phone, EmailAddress
        (Organisation is optional)
    Returns registrar order ID (str) on success, raises on failure.
    """
    sld, tld = _split_domain(domain_name)
    params = {
        'DomainName': domain_name,
        'Years': years,
        # Registrant
        'RegistrantFirstName':     registrant_info.get('FirstName', ''),
        'RegistrantLastName':      registrant_info.get('LastName', ''),
        'RegistrantAddress1':      registrant_info.get('Address1', ''),
        'RegistrantCity':          registrant_info.get('City', ''),
        'RegistrantStateProvince': registrant_info.get('StateProvince', ''),
        'RegistrantPostalCode':    registrant_info.get('PostalCode', ''),
        'RegistrantCountry':       registrant_info.get('Country', 'GB'),
        'RegistrantPhone':         registrant_info.get('Phone', ''),
        'RegistrantEmailAddress':  registrant_info.get('EmailAddress', ''),
        # Tech (same as registrant for simplicity)
        'TechFirstName':     registrant_info.get('FirstName', ''),
        'TechLastName':      registrant_info.get('LastName', ''),
        'TechAddress1':      registrant_info.get('Address1', ''),
        'TechCity':          registrant_info.get('City', ''),
        'TechStateProvince': registrant_info.get('StateProvince', ''),
        'TechPostalCode':    registrant_info.get('PostalCode', ''),
        'TechCountry':       registrant_info.get('Country', 'GB'),
        'TechPhone':         registrant_info.get('Phone', ''),
        'TechEmailAddress':  registrant_info.get('EmailAddress', ''),
        # Admin (same)
        'AdminFirstName':     registrant_info.get('FirstName', ''),
        'AdminLastName':      registrant_info.get('LastName', ''),
        'AdminAddress1':      registrant_info.get('Address1', ''),
        'AdminCity':          registrant_info.get('City', ''),
        'AdminStateProvince': registrant_info.get('StateProvince', ''),
        'AdminPostalCode':    registrant_info.get('PostalCode', ''),
        'AdminCountry':       registrant_info.get('Country', 'GB'),
        'AdminPhone':         registrant_info.get('Phone', ''),
        'AdminEmailAddress':  registrant_info.get('EmailAddress', ''),
        # AuxBilling (same)
        'AuxBillingFirstName':     registrant_info.get('FirstName', ''),
        'AuxBillingLastName':      registrant_info.get('LastName', ''),
        'AuxBillingAddress1':      registrant_info.get('Address1', ''),
        'AuxBillingCity':          registrant_info.get('City', ''),
        'AuxBillingStateProvince': registrant_info.get('StateProvince', ''),
        'AuxBillingPostalCode':    registrant_info.get('PostalCode', ''),
        'AuxBillingCountry':       registrant_info.get('Country', 'GB'),
        'AuxBillingPhone':         registrant_info.get('Phone', ''),
        'AuxBillingEmailAddress':  registrant_info.get('EmailAddress', ''),
    }
    root = _call('namecheap.domains.create', params)
    ns = 'http://api.namecheap.com/xml.response'
    result = root.find(f'.//{{{ns}}}DomainCreateResult')
    if result is None:
        raise Exception('No DomainCreateResult in Namecheap response')
    return result.attrib.get('OrderID', '')


def _split_domain(domain_name):
    """Split 'mybusiness.co.uk' into ('mybusiness', 'co.uk')."""
    parts = domain_name.split('.', 1)
    if len(parts) == 2:
        return parts[0], parts[1]
    return domain_name, ''
