# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details

from odoo import api, exceptions, fields, models, tools, _
from odoo.exceptions import UserError, AccessError, ValidationError
from odoo.osv import expression
import math
from datetime import datetime, time, timedelta
from odoo.tools.float_utils import float_round
from odoo.tools import DEFAULT_SERVER_DATE_FORMAT, ustr
import dateutil.parser


class AccountAnalyticLine(models.Model):
    _inherit = 'account.analytic.line'

    start_time = fields.Float(string='Start Time', digits=(16, 2))
    end_time = fields.Float(string='End Time', digits=(16, 2))
    unit_amount = fields.Float('Duration', default=0.0)
    parent_project = fields.Many2one('project.project', string='Parent Project')


    def _default_start_datetime(self):
        return fields.Datetime.to_string(datetime.combine(fields.Datetime.now(), datetime.min.time()))

    def _default_end_datetime(self):
        return fields.Datetime.to_string(datetime.combine(fields.Datetime.now(), datetime.max.time()))

    start_datetime = fields.Datetime("Start Time", required=True)
    end_datetime = fields.Datetime("End Time", required=True)


    @api.onchange('project_id')
    def _onchange_parent_project_id(self):
        if self.project_id:
            parent_project = self.env['project.project'].search([('sub_project', '=', self.project_id.id)], limit=1)
            if parent_project:
                self.parent_project = parent_project.id
            else:
                self.parent_project = False
        else:
            self.parent_project = False


    @api.onchange('employee_id')
    def _onchange_employee_id(self):
        domain = []
        if self.employee_id and self.employee_id.user_id:
            manager_id = self.env['project.project'].search(
                [('user_id', '=', self.employee_id.user_id.id), ('allow_timesheets', '=', True)]).ids
            emp_project_ids = self.env['project.project'].search(
                [('privacy_visibility', 'in', ('employees', 'portal')), ('allow_timesheets', '=', True)]).ids
            project_ids = self.env['project.project'].search(
                [('privacy_visibility', '=', 'followers'), ('allow_timesheets', '=', True),
                 ('allowed_internal_user_ids', 'in', self.employee_id.user_id.id)]).ids
            consul_ids = self.env['project.sale.line.employee.map'].search([('employee_id', '=', self.employee_id.id)])
            consul_project_ids = [val.project_id.id for val in consul_ids]
            emp_all_project_ids = manager_id + emp_project_ids + project_ids + consul_project_ids
            domain = [('id', 'in', list(set(emp_all_project_ids)))]
        result = {
            'domain': {'project_id': domain},
        }
        return result

    @api.onchange('project_id')
    def _onchange_project_id(self):
        domain = [] if not self.project_id else [('project_id', '=', self.project_id.id)]
        cuser = []
        manager_id = []
        user_ids = []
        consul_project_ids = []
        if not self.project_id:
            cuser = self.env['hr.employee'].search([('user_id', '=', self.env.user.id)]).ids
        if self.project_id:
            consul_ids = self.env['project.sale.line.employee.map'].search([('project_id', '=', self.project_id.id)])
            consul_project_ids = [val.employee_id.id for val in consul_ids]
        if self.project_id and self.project_id.user_id:
            manager_id = self.env['hr.employee'].search([('user_id', '=', self.project_id.user_id.id)]).ids
        if self.project_id and self.project_id.privacy_visibility in ('employees', 'portal'):
            user_ids = self.env['hr.employee'].search([('user_id', '!=', False)]).ids
        if self.project_id and self.project_id.privacy_visibility == 'followers':
            user_ids = self.env['hr.employee'].search(
                [('user_id', 'in', self.project_id.allowed_internal_user_ids.ids)]).ids
        project_all_emp_ids = cuser + manager_id + user_ids + consul_project_ids
        result = {
            'domain': {'task_id': domain, 'employee_id': [('id', 'in', project_all_emp_ids)]},
        }
        if self.project_id != self.task_id.project_id:
            # reset task when changing project
            self.task_id = False
        return result

    _sql_constraints = [
        ('check_start_time_lower_than_24', 'CHECK(start_time <= 24)', 'You cannot have a start hour greater than 24'),
        ('check_start_time_positive', 'CHECK(start_time >= 0)', 'Start hour must be a positive number'),
        ('check_end_time_lower_than_24', 'CHECK(end_time <= 24)', 'You cannot have a end hour greater than 24'),
        ('check_end_time_positive', 'CHECK(end_time >= 0)', 'End hour must be a positive number'),
    ]

    @api.constrains('start_time', 'end_time')
    def _check_validity_start_time_end_time(self):
        for rec in self:
            if rec.start_time and rec.end_time:
                if rec.end_time < rec.start_time:
                    raise exceptions.ValidationError(_('End time cannot be earlier than Start time'))

    @api.onchange('start_time', 'end_time')
    def _onchange_start_end_time(self):
        if self.start_time > 0 and self.end_time > 0:
            res = self.end_time - self.start_time
            if res <= 0:
                raise ValidationError(_("End time cannot be earlier than Start time"))
            self.unit_amount = res

    @api.onchange('start_datetime', 'end_datetime')
    def _onchange_start_end_date_time(self):
        if self.start_datetime and self.end_datetime:
            total_hours = (self.end_datetime - self.start_datetime).total_seconds() / 3600
            self.unit_amount = total_hours

    # @api.onchange('start_time', 'end_time')
    # def _onchange_start_end_time(self):
    #     if self.start_time > 0:
    #         dt = datetime.strptime('26 Sep 2012', '%d %b %Y')
    #         print('HHHHHHHH', dt)
    #         newdatetime = dt.replace(hour=11, minute=59)
    #         print('GGGGGGGGGGGGG', newdatetime)

    @api.model
    def export_data(self, fields):
        index = range(len(fields))
        fields_name = dict(zip(fields, index))
        res = super(AccountAnalyticLine, self).export_data(fields)
        for index, val in enumerate(res['datas']):
            #print("task_id", fields_name)
            if fields_name.get('date') and fields_name.get('date') >= 0:
                tdateindex = fields_name.get('date')
                tdate = res['datas'][index][tdateindex]
                if tdate:
                    res['datas'][index][tdateindex] = datetime.strftime(tdate, "%d/%m/%Y")
            if fields_name.get('start_datetime') and fields_name.get('start_datetime') >= 0:
                start_datetime_index = fields_name.get('start_datetime')
                start_datetime = res['datas'][index][start_datetime_index]
                if start_datetime:
                    res['datas'][index][start_datetime_index] = datetime.strftime(start_datetime, "%d/%m/%Y %H:%M")
            if fields_name.get('end_datetime') and fields_name.get('end_datetime') >= 0:
                end_datetime_index = fields_name.get('end_datetime')
                end_datetime= res['datas'][index][end_datetime_index]
                if end_datetime:
                    res['datas'][index][end_datetime_index] = datetime.strftime(end_datetime, "%d/%m/%Y %H:%M")
            if fields_name.get('task_id') and fields_name.get('task_id') >= 0:
                taskindex = fields_name.get('task_id')
                ttask = res['datas'][index][taskindex]
                if type(ttask) == bool:
                    res['datas'][index][taskindex] = ''
            if fields_name.get('start_time') and fields_name.get('start_time') >= 0:
                starttimeindex = fields_name.get('start_time')
                starttime = float(res['datas'][index][starttimeindex])
                if starttime:
                    start_time = tools.format_duration(starttime)
                    res['datas'][index][starttimeindex] = start_time
            if fields_name.get('end_time') and fields_name.get('end_time') >= 0:
                endtimeindex = fields_name.get('end_time')
                endtime = float(res['datas'][index][endtimeindex])
                if endtime:
                    end_time = tools.format_duration(endtime)
                    res['datas'][index][endtimeindex] = end_time
        return res

    @api.model
    def create(self, vals):
        if vals.get('unit_amount') == 0.0:
            raise ValidationError(_("Your can not fill 0.0 hour entry"))
        if vals.get('unit_amount') >= 24.0:
            raise ValidationError(_("Your can not fill more than 24.0 hour entry"))
        value = super(AccountAnalyticLine, self).create(vals)
        if value and value.project_id:
            value.project_id._onchange_calculate_timesheet_hours()
            value.project_id._compute_calc()
        return value


    def write(self, vals):
        if vals.get('unit_amount') == 0.0:
            raise ValidationError(_("Your can not fill 0.0 hour entry"))
        res = super(AccountAnalyticLine, self).write(vals)
        if self.project_id:
            self.project_id._onchange_calculate_timesheet_hours()
        return res

    @api.onchange('start_datetime', 'end_datetime')
    def _onchange_start_end_date(self):
        if self.start_datetime:
            self.date = self.start_datetime.date()
