import stdnum.exceptions
import logging
from sql import Column, Literal
from sql.aggregate import Min
from sql.functions import CharLength
from stdnum import get_cc_module
from decimal import getcontext, Decimal, ROUND_HALF_UP
from trytond.i18n import gettext
from trytond.model import (
    DeactivableMixin, Index, ModelSQL, ModelView, MultiValueMixin, Unique,
    ValueMixin, convert_from, fields, sequence_ordered)
from trytond.model.exceptions import AccessError
from trytond.pool import Pool
from trytond.pyson import Bool, Eval
from trytond.tools import is_full_text, lstrip_wildcard
from trytond.transaction import Transaction, inactive_records
from trytond.wizard import Button, StateTransition, StateView, Wizard
from datetime import date, timedelta, datetime

logger = logging.getLogger(__name__)

class Price(
        DeactivableMixin, ModelSQL, ModelView,
        MultiValueMixin):
    "Price"
    __name__ = 'price.price'
    _rec_name = 'price_index'
    price = fields.Many2One('price.price',"Composite")
    price_index = fields.Char("Price index", required=True)
    price_desc = fields.Char("Description", required=True)
    price_period = fields.Many2One('product.month',"Period")
    price_curve_type = fields.Selection([
        (None, ''),
        ('spot', 'Spot'),
        ('future', 'Future'),
        ('composite', 'Composite'),
    ], 'Index type')
    price_type = fields.Many2One('price.fixtype', "Fixation type")
    price_unit = fields.Many2One('product.uom', "Unit")
    price_currency = fields.Many2One('currency.currency', "Currency")
    price_area = fields.Many2One('price.area',"Market area")
    price_calendar = fields.Many2One('price.calendar',"Calendar")
    price_values = fields.One2Many('price.price_value', 'price', "Prices Values")
    price_composite = fields.One2Many('price.composite','price',"Composites")
    price_product = fields.One2Many('price.product', 'price', "Product")
    price_ct_size = fields.Numeric("Ct size")

    def get_qt(self,nb_ct,unit):
        Uom = Pool().get('product.uom')
        return round(Decimal(Uom.compute_qty(self.price_unit, float(self.price_ct_size * nb_ct), unit)),2)

    def get_price_per_qt(self,price,unit,currency):
        price_qt = float(0)
        Uom = Pool().get('product.uom')
        Currency = Pool().get('currency.currency')
        rates = Currency._get_rate([self.price_currency])
        if rates[self.price_currency.id]:
            price_qt = float(price) * Uom.compute_qty(unit, float(1), self.price_unit) * float(rates[self.price_currency.id])
        return round(price_qt,2)

    def get_amount_nb_ct(self,price,nb_ct,unit,currency):
        amount = Decimal(0)
        Uom = Pool().get('product.uom')
        if price:
            amount = Decimal(self.get_price_per_qt(price,unit,currency)) * Decimal(Uom.compute_qty(self.price_unit, float(self.price_ct_size * nb_ct), unit))
        return round(amount,2)

    def get_price(self,dt,unit,currency,last=False):
        price = float(0)
        PV = Pool().get('price.price_value')
        if self.price_values:
            dt = dt.strftime("%Y-%m-%d")
            pv = PV.search([('price','=',self.id),('price_date','=',dt)])
            if not pv and last:
                pv = PV.search([('price','=',self.id)],order=[('price_date', 'DESC')])
            if pv:
                price = self.get_price_per_qt(pv[0].price_value,unit,currency)
        return round(price,2)

class FixType(ModelSQL,ModelView):
    "Fixation type"
    __name__ = 'price.fixtype'
    name = fields.Char("Fixation type")

class Composite(ModelSQL,ModelView):
    "Composite"
    __name__ = 'price.composite'
    price = fields.Many2One(
        'price.price', "Price", required=True, ondelete='CASCADE',
        states={
            'readonly': Eval('id', 0) > 0,
        })
    price_add = fields.Many2One('price.price',"Price index")
    ratio = fields.Numeric("%")

class MarketArea(ModelSQL,ModelView):
    "Market Area"
    __name__ = 'price.area'
    name = fields.Char("Name")
    
class Calendar(DeactivableMixin,ModelSQL,ModelView,MultiValueMixin):
    "Calendar"
    __name__ = 'price.calendar'
    name = fields.Char("Name")
    calendar_line = fields.One2Many('price.calendar.line','calendar',"Calendar lines")

    def IsQuote(self,dt):
        CL = Pool().get('price.calendar.line')
        if self.calendar_line:
            dt = dt.strftime("%Y-%m-%d")
            cl = CL.search([('calendar','=',self.id),('price_date','=',dt)])
            if cl:
                logger.info("ISQUOTE:%s",cl)
                return False
            else:
                return True
    
class CalendarLine(DeactivableMixin,ModelSQL,ModelView,MultiValueMixin):
    "Calendar line"
    __name__ = 'price.calendar.line'
    calendar = fields.Many2One('price.calendar',"Calendar")
    price_date = fields.Date("Date")
    price_state = fields.Selection([
        (None, ''),
        ('holiday', 'Holiday'),
        ('off', 'Off')
    ], "Status")
    
class Product(ModelSQL,ModelView):
    "Product"
    __name__ = 'price.product'
    price = fields.Many2One('price.price',"Price index")
    product = fields.Many2One('product.product',"Product")
