# This file is part of Tryton.  The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
import datetime

from trytond.i18n import gettext
from trytond.modules.stock_supply.exceptions import SupplyWarning
from trytond.pool import Pool, PoolMeta
from trytond.pyson import Eval, If
from trytond.transaction import check_access
from trytond.wizard import StateAction


class OrderPoint(metaclass=PoolMeta):
    __name__ = 'stock.order_point'

    @classmethod
    def __setup__(cls):
        super(OrderPoint, cls).__setup__()

        cls.product.domain = [
            cls.product.domain,
            If(Eval('type') == 'production',
                ('producible', '=', True),
                ()),
            ]

        cls.warehouse_location.states['invisible'] &= (
            Eval('type') != 'production')
        cls.warehouse_location.states['required'] |= (
            Eval('type') == 'production')

        option = ('production', 'Production')
        if option not in cls.type.selection:
            cls.type.selection.append(option)

    @classmethod
    def _type2field(cls, type=None):
        if type == 'production':
            return 'warehouse_location'
        result = super(OrderPoint, cls)._type2field(type=type)
        if type is None:
            result['production'] = 'warehouse_location'
        return result

    def get_location(self, name):
        location = super(OrderPoint, self).get_location(name)
        if self.type == 'production':
            return self.warehouse_location.id
        return location


class LocationLeadTime(metaclass=PoolMeta):
    __name__ = 'stock.location.lead_time'

    @classmethod
    def _get_extra_lead_times(cls):
        pool = Pool()
        Configuration = pool.get('production.configuration')
        config = Configuration(1)
        supply_period = config.get_multivalue('supply_period')
        extra = super(LocationLeadTime, cls)._get_extra_lead_times()
        extra.append(supply_period or datetime.timedelta(0))
        return extra


class StockSupply(metaclass=PoolMeta):
    __name__ = 'stock.supply'

    production = StateAction('stock_supply_production.act_production_request')

    @classmethod
    def types(cls):
        return super(StockSupply, cls).types() + ['production']

    def transition_create_(self):
        pool = Pool()
        Date = pool.get('ir.date')
        Move = pool.get('stock.move')
        Warning = pool.get('res.user.warning')
        today = Date.today()
        with check_access():
            moves = Move.search([
                    ('from_location.type', '=', 'production'),
                    ('to_location.type', '=', 'storage'),
                    ('state', '=', 'draft'),
                    ('planned_date', '<', today),
                    ], order=[])
        if moves:
            key = '%s@%s' % (self.__name__, today)
            if Warning.check(key):
                raise SupplyWarning(
                    key,
                    gettext('stock_supply_production.msg_late_productions'))
        return super(StockSupply, self).transition_create_()

    @property
    def _production_parameters(self):
        parameters = {}
        # Use getattr because start is empty when run by cron
        if getattr(self.start, 'warehouses', None):
            parameters['warehouses'] = self.start.warehouses
        return parameters

    def generate_production(self, clean):
        pool = Pool()
        Production = pool.get('production')
        return Production.generate_requests(
            clean=clean, **self._production_parameters)

    def transition_production(self):
        return self.next_action('production')
