# This file is part of Tryton.  The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
from datetime import datetime
from trytond.report import Report
from trytond.model import ModelView, ModelSQL, fields, Workflow
from trytond.pyson import Eval, If, In, Get
from trytond.pool import Pool
from trytond.transaction import Transaction
from .exceptions import CrmConfigurationError
from trytond.i18n import gettext

STATES = {'readonly': (Eval('state') != 'draft')}

RESPONSE = {
    'numeric_1_5': [(str(n+1), str(n+1)) for n in range(5)],
    'yes_no': [
        ('yes', 'Yes'),
        ('no', 'No'),
        ('not_apply', 'Not Apply'),
    ],
}


class SurveyGroup(ModelSQL, ModelView):
    "Survey Group"
    __name__ = "crm.survey.group"
    name = fields.Char('Name', required=True, select=True)
    code = fields.Char('Code', select=True)
    description = fields.Text('Description', select=True)


class SurveyTemplate(ModelSQL, ModelView):
    "Survey Template"
    __name__ = "crm.survey_template"
    name = fields.Char('Name', required=True, select=True)
    code = fields.Char('Code', required=True, select=True)
    active = fields.Boolean('Active')
    lines = fields.One2Many('crm.survey_template.line',
        'template', 'Lines')


class SurveyTemplateLine(ModelSQL, ModelView):
    "Survey Template Line"
    __name__ = "crm.survey_template.line"
    _rec_name = 'ask'
    template = fields.Many2One('crm.survey_template',
        'Template Survey', required=True)
    group = fields.Many2One('crm.survey.group',
        'Survey Group', required=False)
    sequence = fields.Integer('Sequence', required=True, select=True)
    ask = fields.Char('Ask', required=True, select=True)
    type_response = fields.Selection([
        ('numeric_1_5', 'Numeric 1-5'),
        ('free_text', 'Free Text'),
        ('yes_no', 'Yes or No'),
        ('boolean', 'Boolean'),
    ], 'Type Response', required=True, select=True)

    @staticmethod
    def default_type_response():
        return 'yes_no'


class Survey(Workflow, ModelSQL, ModelView):
    "Survey"
    __name__ = "crm.survey"
    number = fields.Char('Number', readonly=True, select=True)
    party = fields.Many2One('party.party', 'Party', states=STATES)
    operator = fields.Many2One('party.party', 'Operator', states=STATES)
    date_time = fields.DateTime('Date', required=True, states=STATES)
    template = fields.Many2One('crm.survey_template',
        'Survey Template', required=True, states=STATES)
    company = fields.Many2One('company.company', 'Company', required=True,
        domain=[('id', If(In('company',
        Eval('context', {})), '=', '!='), Get(Eval('context', {}),
        'company', 0)), ], states=STATES)
    state = fields.Selection([
        ('draft', 'Draft'),
        ('process', 'Process'),
        ('done', 'Done'),
        ('cancelled', 'Cancelled'),
        ], 'State', readonly=True, required=True)
    state_string = state.translated('state')
    lines = fields.One2Many('crm.survey.line', 'survey',
        'Lines', states=STATES)
    notes = fields.Text('Notes', states=STATES)

    @classmethod
    def __setup__(cls):
        super(Survey, cls).__setup__()
        cls._order.insert(0, ('number', 'ASC'))
        cls._transitions |= set((
            ('draft', 'process'),
            ('process', 'done'),
            ('process', 'cancelled'),
            ('cancelled', 'draft'),
            ('process', 'draft'),
            ))
        cls._buttons.update({
            'draft': {
                'invisible': Eval('state').in_(['draft', 'done']),
                },
            'cancel': {
                'invisible': Eval('state') != 'process',
                },
            'done': {
                'invisible': Eval('state') != 'process',
                },
            'process': {
                'invisible': Eval('state') != 'draft',
                },
            })

    @staticmethod
    def default_company():
        return Transaction().context.get('company')

    @staticmethod
    def default_state():
        return 'draft'

    @staticmethod
    def default_date_time():
        return datetime.now()

    @classmethod
    @ModelView.button
    @Workflow.transition('draft')
    def draft(cls, records):
        pass

    @classmethod
    @ModelView.button
    @Workflow.transition('cancelled')
    def cancel(cls, records):
        pass

    @classmethod
    @ModelView.button
    @Workflow.transition('done')
    def done(cls, records):
        pass

    @classmethod
    @ModelView.button
    @Workflow.transition('process')
    def process(cls, records):
        cls.set_number(records)

    @fields.depends('template', 'lines')
    def on_change_template(self):
        lines_to_add = []
        if self.template:
            sequence = 1
            for tline in self.template.lines:
                lines_to_add.append({
                    'sequence': sequence,
                    'line_ask': tline.id,
                })
                sequence += 1
        self.lines = lines_to_add

    @classmethod
    def set_number(cls, records):
        '''
        Fill the number field with the survey sequence
        '''
        pool = Pool()
        Config = pool.get('crm.configuration')
        config = Config(1)

        for record in records:
            if record.number:
                continue
            if not config.survey_sequence:
                raise CrmConfigurationError(
                    gettext('crm.msg_missing_sequence_survey'))
            number = config.survey_sequence.get()
            cls.write([record], {'number': number})


class SurveyLine(ModelSQL, ModelView):
    "Survey Line"
    __name__ = "crm.survey.line"
    survey = fields.Many2One('crm.survey',
        'Survey', required=True)
    sequence = fields.Integer('Sequence', required=True)
    line_ask = fields.Many2One('crm.survey_template.line',
        'Survey Line', required=True)
    response = fields.Selection('selection_response', 'Response',
        depends=['line_ask'])
    comments = fields.Text('Comments')
    group = fields.Many2One('crm.survey.group',
        'Survey Group', states={
            'readonly': True
        })

    @classmethod
    def __setup__(cls):
        super(SurveyLine, cls).__setup__()
        cls._order.insert(0, ('sequence', 'ASC'))

    @fields.depends('line_ask', 'response')
    def selection_response(self):
        res = [('', '')]
        if self.line_ask and self.line_ask.type_response in ('numeric_1_5', 'yes_no'):
            res = RESPONSE.get(self.line_ask.type_response)
        return res

    @fields.depends('line_ask', 'group')
    def on_change_with_line_ask(self):
        if self.line_ask and self.line_ask.group:
            if self.line_ask.type_response == 'yes_no':
                return 'yes'
            elif self.line_ask.type_response == 'numeric_1_5':
                return '5'

    @fields.depends('line_ask', 'group')
    def on_change_with_group(self):
        if self.line_ask and self.line_ask.group:
            return self.line_ask.group.id


class SurveyReport(Report):
    "Survey Report"
    __name__ = "crm.survey"
