# -*- coding: utf-8 -*-
from datetime import datetime
import magento
import logging
import xmlrpclib
import socket

from trytond.pool import PoolMeta, Pool
from trytond.transaction import Transaction
from trytond.pyson import Eval
from trytond.model import ModelView, ModelSQL, fields
from .api import OrderConfig

__metaclass__ = PoolMeta
__all__ = ['Channel', 'MagentoTier']

MAGENTO_STATES = {
    'invisible': ~(Eval('source') == 'magento'),
    'required': Eval('source') == 'magento'
}

INVISIBLE_IF_NOT_MAGENTO = {
    'invisible': ~(Eval('source') == 'magento'),
}

logger = logging.getLogger('magento')


def batch(iterable, n=1):
    l = len(iterable)
    for ndx in range(0, l, n):
        yield iterable[ndx:min(ndx + n, l)]


class Channel:
    """
    Sale Channel model
    """
    __name__ = 'sale.channel'

    # Instance
    magento_url = fields.Char(
        "Magento Site URL", states=MAGENTO_STATES, depends=['source']
    )
    magento_api_user = fields.Char(
        "API User", states=MAGENTO_STATES, depends=['source']
    )
    magento_api_key = fields.Char(
        "API Key", states=MAGENTO_STATES, depends=['source']
    )
    magento_carriers = fields.One2Many(
        "magento.instance.carrier", "channel", "Carriers / Shipping Methods",
        states=INVISIBLE_IF_NOT_MAGENTO, depends=['source']
    )
    magento_order_prefix = fields.Char(
        'Sale Order Prefix',
        help="This helps to distinguish between orders from different channels",
        states=INVISIBLE_IF_NOT_MAGENTO, depends=['source']
    )

    # website
    magento_website_id = fields.Integer(
        'Website ID', readonly=True,
        states=INVISIBLE_IF_NOT_MAGENTO, depends=['source']
    )
    magento_website_name = fields.Char(
        'Website Name', readonly=True,
        states=INVISIBLE_IF_NOT_MAGENTO, depends=['source']
    )
    magento_website_code = fields.Char(
        'Website Code', readonly=True,
        states=INVISIBLE_IF_NOT_MAGENTO, depends=['source']
    )
    magento_root_category_id = fields.Integer(
        'Root Category ID', states=INVISIBLE_IF_NOT_MAGENTO, depends=['source']
    )
    magento_store_name = fields.Char(
        'Store Name', readonly=True, states=INVISIBLE_IF_NOT_MAGENTO,
        depends=['source']
    )
    magento_store_id = fields.Integer(
        'Store ID', readonly=True, states=INVISIBLE_IF_NOT_MAGENTO,
        depends=['source']
    )

    #: Checking this will make sure that only the done shipments which have a
    #: carrier and tracking reference are exported.
    magento_export_tracking_information = fields.Boolean(
        'Export tracking information', help='Checking this will make sure'
        ' that only the done shipments which have a carrier and tracking '
        'reference are exported. This will update carrier and tracking '
        'reference on magento for the exported shipments as well.',
        states=INVISIBLE_IF_NOT_MAGENTO, depends=['source']
    )
    magento_taxes = fields.One2Many(
        "sale.channel.magento.tax", "channel", "Taxes",
        states=INVISIBLE_IF_NOT_MAGENTO, depends=['source']
    )
    magento_price_tiers = fields.One2Many(
        'sale.channel.magento.price_tier', 'channel', 'Default Price Tiers',
        states=INVISIBLE_IF_NOT_MAGENTO, depends=['source']
    )
    product_listings = fields.One2Many(
        'product.product.channel_listing', 'channel', 'Product Listings',
    )
    magento_payment_gateways = fields.One2Many(
        'magento.instance.payment_gateway', 'channel', 'Payments',
    )

    @classmethod
    def __setup__(cls):
        """
        Setup the class before adding to pool
        """
        super(Channel, cls).__setup__()
        cls._sql_constraints += [
            (
                'unique_magento_channel',
                    'UNIQUE(magento_url, magento_website_id, magento_store_id)',
                'This store is already added'
            )
        ]
        cls._error_messages.update({
            "connection_error": "Incorrect API Settings! \n"
                "Please check and correct the API settings on channel.",
            "multiple_channels": 'Selected operation can be done only for one'
                ' channel at a time',
            'invalid_magento_channel':
                'Current channel does not belongs to Magento !'
        })
        cls._buttons.update({
            'import_magento_carriers': {
                'invisible': Eval('source') != 'magento'
            },
            'configure_magento_connection': {
                'invisible': Eval('source') != 'magento'
            }
        })

    def validate_magento_channel(self):
        """
        Make sure channel source is magento
        """
        if self.source != 'magento':
            self.raise_user_error('invalid_magento_channel')

    @classmethod
    def get_source(cls):
        """
        Get the source
        """
        res = super(Channel, cls).get_source()
        res.append(('magento', 'Magento'))
        return res

    @staticmethod
    def default_magento_order_prefix():
        """
        Sets default value for magento order prefix
        """
        return 'mag_'

    @staticmethod
    def default_magento_root_category_id():
        """
        Sets default root category id. Is set to 1, because the default