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

from trytond.model import ModelView, ModelSQL, fields, Workflow
from trytond.pyson import Eval
from trytond.pool import Pool
from trytond.wizard import Wizard, StateView, Button, StateTransition


class Maintenance(Workflow, ModelSQL, ModelView):
    'Hotel Maintenance'
    __name__ = 'hotel.maintenance'
    STATES = {'readonly': Eval('state') != 'draft'}
    STATES_FINISH = {
        'readonly': Eval('state') != 'draft',
        'required': Eval('state') == 'finished'
    }
    room = fields.Many2One('hotel.room', 'Room', required=True,
        states=STATES)
    register_date = fields.Date('Date', states=STATES, required=True,
        help='The date of register of the issue')
    start_date = fields.Date('Start Maintenance', states={
        'required': Eval('state').in_(['in_progress', 'finished']),
        'readonly': Eval('state') == 'finished'
    })
    end_date = fields.Date('End Maintenance', states={
        'required': Eval('state').in_(['in_progress', 'finished']),
        'readonly': Eval('state') == 'finished'
    })
    total_days = fields.Function(fields.Integer('Total Days'), 'get_days')
    issue = fields.Text('Issue', required=True, states={
        'readonly': Eval('state').in_(['finished', 'cancelled'])
    })
    action = fields.Text('Action', states={
        'required': Eval('state') == 'finished',
        'readonly': Eval('state') == 'finished'
    }, depends=['state'])
    inspected_by = fields.Many2One('company.employee', 'Inspected By',
        states=STATES_FINISH)
    state = fields.Selection([
            ('draft', 'Draft'),
            ('confirmed', 'Confirmed'),
            ('in_progress', 'In progress'),
            ('finished', 'Finished'),
            ('cancelled', 'Canceled'),
        ], 'State', readonly=True)
    criticality = fields.Selection([
            ('low', 'Low'),
            ('important', 'Important'),
            ('urgent', 'Urgent'),
            ], 'Criticality', required=True)

    @classmethod
    def __setup__(cls):
        super(Maintenance, cls).__setup__()
        cls._transitions |= set((
            ('draft', 'confirmed'),
            ('draft', 'cancelled'),
            ('confirmed', 'draft'),
            ('confirmed', 'in_progress'),
            ('cancelled', 'draft'),
            ('confirmed', 'cancelled'),
            ('in_progress', 'finished'),
            ('finished', 'in_progress'),
        ))
        cls._buttons.update({
            'confirm': {
                'invisible': Eval('state') != 'draft',
            },
            'in_progress': {
                'invisible': Eval('state') != 'confirmed',
            },
            'finish': {
                'invisible': Eval('state') != 'in_progress',
            },
            'draft': {
                'invisible': Eval('state').in_(['draft', 'cancelled']),
            },
            'cancel': {
                'invisible': Eval('state') == 'finished',
            }
        })

    @staticmethod
    def default_state():
        return 'draft'

    @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('confirmed')
    def confirm(cls, records):
        pass

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

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

    @fields.depends('start_date', 'end_date')
    def on_change_start_date(self):
        if not self.start_date:
            self.end_date = None

    def get_days(self, name):
        if self.end_date and self.start_date:
            return (self.end_date - self.start_date).days

    # FIXME
    def check_method(self):
        """
        Check the methods.
        FIXME
        """
        Operation = Pool().get('hotel.operation')
        Operation().check_dates(self.start_date, self.end_date, self.room,
            self.operation)


class NightAudit(ModelSQL, ModelView):
    'Night Audit'
    __name__ = 'hotel.night_audit'
    company = fields.Many2One('company.company', 'Company', required=True,
        readonly=True)
    audit_date = fields.Date('Date', required=True, readonly=True)


class NightAuditStart(ModelView):
    'Night Audit'
    __name__ = 'hotel.night_audit.start'
    company = fields.Many2One('company.company', 'Company', required=True)


class NightAuditWizard(Wizard):
    'Night Audit Wizard'
    __name__ = 'hotel.night_audit.wizard'
    """
    This is the wizard for night audit
    """
    start = StateView(
        'hotel.night_audit.start',
        'hotel.night_audit_start_view_form', [
            Button('Cancel', 'end', 'tryton-cancel'),
            Button('Ok', 'accept', 'tryton-ok'),
        ]
    )
    accept = StateTransition()

    def update_rooms(self):
        pool = Pool()
        Room = pool.get('hotel.room')
        rooms = Room.search([])
        Room.write(rooms, {
            "check_in_today": None,
            "check_out_today": None,
            "state": "dirty",
        })

    def transition_accept(self):
        pool = Pool()
        FolioCharge = pool.get('hotel.folio.charge')
        Booking = pool.get('hotel.booking')
        Config = pool.get('hotel.configuration')
        NightAudit = pool.get('hotel.night_audit')
        Date = pool.get('ir.date')
        pending = FolioCharge.search([
            ('move', '=', None),
            ('product.template.type', '=', 'goods'),
        ])
        for charge in pending:
            charge.do_stock_move()

        config = Config.get_configuration()

        today = Date.today()
        today_30 = Date.today() - timedelta(days=30)
        bookings = Booking.search([
            ('lines.arrival_date', '<=', today),
            ('lines.departure_date', '>', today_30),
            ('state', 'in', ['confirmed']),
        ])

        # This is temporal fix for folios without occupancy
        _bookings = Booking.search([
            ('state', 'in', ['confirmed']),
        ])
        for booking in _bookings:
            for folio in booking.lines:
                if folio.occupancy:
                    continue
                folio.add_occupancy()

        Booking.add_charges_occupancy(bookings)
        if config.accounting_revenue == 'recognise_revenue':
            Booking.do_revenue_accounting(bookings)

        NightAudit.create([{
            'company': self.start.company.id,
            'audit_date': today,
        }])
        return 'end'
