from odoo import models, fields, api, _
from odoo.exceptions import UserError, ValidationError
from odoo.tools import float_compare, float_round

from datetime import datetime
import datetime as dt
from datetime import timedelta


class BuyVacation(models.Model):
    _name = "buy.vacation"
    _description = "Buy Vacation"
    _rec_name = 'employee_id'
    _order = 'id desc'
    _inherit = ['mail.thread', 'mail.activity.mixin']

    employee_id = fields.Many2one('hr.employee', 'Employee', required=True)
    job_id = fields.Many2one(related='employee_id.job_id', readonly=True)
    department_id = fields.Many2one(related='employee_id.department_id', readonly=True)
    date = fields.Date()
    leave_buy = fields.Float('Vacation balance for purchase')
    monthly_salary = fields.Float(store=True)
    notes = fields.Text()
    attach_ids = fields.One2many('ir.attachment', 'att_vacation_ids')
    account_move_id = fields.Many2one('account.move')
    journal_id = fields.Many2one('account.journal', _('Journal'))
    account_debit_id = fields.Many2one('account.account', _('Account'))
    leave_amount = fields.Float()
    leave_balance = fields.Float(string="Current annual leave balance",store=True,)
    # holiday_status_id = fields.Many2one('hr.holidays.status', domain=[('id', 'in', [])])
    state = fields.Selection([
        ('draft', 'Draft'),
        ('send', 'Send'),
        ('d_manager', 'Direct Manager'),
        ('m_manager', 'Management Manager'),
        ('hr_manager', 'HR Manager'),
        ('approve', 'Approved'),
        ('refuse', 'Refused'),
                              ], default="draft",tracking=True)

    @api.onchange("employee_id")
    def _compute_leave_balance(self):
        for rec in self:
            rec.monthly_salary = rec.employee_id.contract_id.total_net
            balance = self.env['hr.holidays'].search([('employee_id', '=', rec.employee_id.id), ('type', '=', 'add'),
                                                      ('holiday_status_id.leave_type', '=', 'annual'),
                                                      ('check_allocation_view', '=', 'balance')
                                                      ], order='id desc', limit=1)
            rec.leave_balance = balance.remaining_leaves

    # get amount of salary day from salary month and get leave buy
    @api.onchange("leave_buy")
    def _compute_leave_amount(self):
        for rec in self:
           rec.monthly_salary = rec.employee_id.contract_id.total_net
           if rec.monthly_salary:
              salary_day = rec.monthly_salary/30
              rec.leave_amount = rec.leave_buy*salary_day

    @api.constrains('leave_buy', 'leave_balance')
    def leave_balance_constrain(self):
        for item in self:
            employee_balance = self.env['hr.holidays'].search(
                [('type', '=', 'add'), ('holiday_status_id.leave_type', '=', 'annual'),
                 ('employee_id', '=', item.employee_id.id), ('check_allocation_view', '=', 'balance')],
                limit=1)
            #if item.leave_buy > item.leave_balance:
              #  raise UserError(_('The Days of Leave to buy must equal or less than leave balance'))

            if item.leave_buy > employee_balance.remaining_leaves:
                raise exceptions.ValidationError(_('The Days of Leave to buy must equal or less than remaining leaves'))

    @api.constrains('leave_amount')
    def _check_leave_amount(self):
        if self.leave_amount == 0.0:
            raise ValidationError(_('The leave amount amount cannot be Zero.'))

    def send(self):
        self._compute_leave_balance()
        self.state = 'send'

    def d_manager(self):
        self._compute_leave_balance()
        self.state = 'd_manager'

    def m_manager(self):
        self._compute_leave_balance()
        self.state = 'm_manager'

    def hr_manager(self):
        self._compute_leave_balance()
        self.state = 'hr_manager'

    def approve(self):
        for item in self:
            item._compute_leave_balance()
            employee_balance = self.env['hr.holidays'].search(
                [('type', '=', 'add'), ('holiday_status_id.leave_type', '=', 'annual'),
                 ('employee_id', '=', item.employee_id.id), ('check_allocation_view', '=', 'balance')],
                limit=1)
            employee_balance.write({'remaining_leaves': employee_balance.remaining_leaves - item.leave_buy})
            debit_line_vals = {
                'name': 'debit',
                'debit': item.leave_amount,
                'date': item.date,
                'account_id': item.account_debit_id.id,
                'partner_id': item.employee_id.user_id.partner_id.id
            }
            credit_line_vals = {
                'name': 'credit',
                'credit': item.leave_amount,
                'date': item.date,
                'account_id': item.journal_id.default_account_id.id,
                'partner_id': item.employee_id.user_id.partner_id.id
            }
            move_id = self.env['account.move'].create({
                'state': 'draft',
                'journal_id': item.journal_id.id,
                'date': item.date,
                'ref': 'Buy Vacation for "%s" ' % item.employee_id.name,
                'line_ids': [(0, 0, debit_line_vals), (0, 0, credit_line_vals)]
            })

            self.write({
                'state': 'approve',
                'account_move_id': move_id.id
            })

        self.state = 'approve'

    def refuse(self):
        self.state = 'refuse'

    def draft_state(self):
        for item in self:
            employee_balance = self.env['hr.holidays'].search(
                [('type', '=', 'add'), ('holiday_status_id.leave_type', '=', 'annual'),
                 ('employee_id', '=', item.employee_id.id), ('check_allocation_view', '=', 'balance')],
                limit=1)
            employee_balance.write({'remaining_leaves': employee_balance.remaining_leaves + item.leave_buy})
            if item.account_move_id.state == 'posted':
                raise UserError(
                    _('You can not cancel account move "%s" in state not draft') % item.account_move_id.name)
            else:
                item.account_move_id.unlink()
                item.write({
                    'account_move_id': False
                })
                item.account_debit_id = False
                item.journal_id = False
            item._compute_leave_balance()
            item.write({'state': 'draft'})

    def unlink(self):
        for rec in self:
            if rec.state != 'draft':
                raise UserError(_('You can not delete a record not in draft state'))
        return super(BuyVacation, self).unlink()


class BuyVacationAttach(models.Model):
    _inherit = 'ir.attachment'

    att_vacation_ids = fields.Many2one(comodel_name='buy.vacation')
