import time
from calendar import monthrange

from netforce.model import Model, fields, get_model
from netforce.access import get_active_user, get_active_company
from netforce.utils import get_data_path

from . import utils

class LaborCostEntry(Model):
    _name="clinic.labor.cost.entry"
    _string="Labor Cost Entry"
    _multi_company=True
    #_key=['name']

    def _get_all(self,ids,context={}):
        res={}
        for obj in self.browse(ids):
            total=0.0
            total_qty=0
            dcost=0
            ncost=0
            for line in obj.lines:
                amt=line.amount or 0
                qty=line.qty or 0
                if line.type=='nurse':
                    ncost+=amt
                else:
                    dcost+=amt
                total_qty+=qty
                total+=amt
            res[obj.id]={
                'total':total,
                'total_qty': total_qty,
                'dcost': dcost,
                'ncost': ncost,
            }
        return res

    _fields={
        'name': fields.Char("Name", required=True,search=True),
        'date': fields.Date("Month",required=True),
        'date_from': fields.Date("From",required=True),
        'date_to': fields.Date("To",required=True),
        'total': fields.Float("Total (Baht)", function="_get_all",function_multi=True),
        'total_qty': fields.Float("Total Qty", function="_get_all",function_multi=True),
        'dcost': fields.Float("Doctor Cost", function="_get_all",function_multi=True),
        'ncost': fields.Float("Nurse Cost", function="_get_all",function_multi=True),
        "lines": fields.One2Many("clinic.labor.cost.entry.line", "entry_id", "Lines"),
        "nurse_lines": fields.One2Many("clinic.labor.cost.entry.line", "entry_id", "Nurse Lines",domain=[['type','=','nurse']]),
        "doctor_lines": fields.One2Many("clinic.labor.cost.entry.line", "entry_id", "Doctor Lines",domain=[['type','=','doctor']]),
        #"work_state": fields.Selection([["part_time","Part Time"],["full_time","Full Time"]],"Working Status",search=True),
        'categ_id': fields.Many2One("clinic.staff.categ", "Category",search=True),
        "state": fields.Selection([["draft","Draft"],["approved","Approved"]],"Status"),
        'user_id': fields.Many2One("base.user","Approver",search=True),
        'note': fields.Text("Note"),
        'company_id': fields.Many2One("company","Company"),
        'department_id': fields.Many2One("clinic.department","Department",search=True),
        'branch_id': fields.Many2One("clinic.branch","Branch",search=True),
    }

    def _get_date_from(self,context={}):
        year,month=time.strftime("%Y-%m").split("-")
        return '%s-%s-01'%(year,month)

    def _get_date_to(self,context={}):
        year,month,day=time.strftime("%Y-%m-%d").split("-")
        weekday, total_day=monthrange(int(year), int(month))
        return "%s-%s-%s"%(year,month,total_day)

    _defaults={
        'name': '/',
        'date': lambda *a: time.strftime("%Y-%m-%d"),
        'date_from': _get_date_from,
        'date_to': _get_date_to,
        'user_id': lambda *a: get_active_user(),
        'company_id': lambda *a: get_active_company(),
        'state': 'draft',
    }

    _order="date_from desc,branch_id,department_id"
    
    def compute(self,ids,context={}):
        obj=self.browse(ids)[0]
        year,month,day=obj.date.split("-")
        line_ids=[]
        dom=[
            ['date','>=',obj.date_from],
            ['date','<=',obj.date_to],
        ]
        if obj.branch_id:
            dom.append(['labor_cost_id.cycle_item_id.branch_id','=',obj.branch_id.id])
        if obj.department_id:
            dom.append(['labor_cost_id.cycle_item_id.department_id','=',obj.department_id.id])
        if obj.categ_id:
            dom.append(['staff_id.categ_id','=',obj.categ_id.id])
        for lc_id in get_model("clinic.labor.cost.line").search(dom):
            line_ids.append(lc_id)
        staffs={}
        for line in get_model("clinic.labor.cost.line").browse(line_ids):
            staff=line.staff_id
            qty=line.qty
            amt=line.amount
            #state=line.state or staff.state
            categ=line.categ_id
            dpt=staff.department_id
            citem=line.labor_cost_id.cycle_item_id
            if not dpt:
                dpt=citem.department_id
            if not staffs.get(staff.id):
                staffs[staff.id]={
                    'staff_type': staff.type,
                    'department_id': dpt.id,
                    'qty': 0,
                    'amt': 0,
                    'rate': 0, # XXX for special nurse
                    #'state': state,
                    'categ_id': categ.id,
                    'report_staff_id': get_model("clinic.report.staff").create({
                        'date_from': obj.date_from,
                        'date_to': obj.date_to,
                        'staff_id': staff.id,
                        'entry_id': obj.id,
                        'staff_type': staff.type,
                    }),
                    'items': set(),
                }
            staffs[staff.id]['qty']+=qty
            staffs[staff.id]['amt']+=amt
            staffs[staff.id]['items'].update({citem.id})
        lines=[]
        timenow=time.strftime("%Y-%m-%d")
        for staff_id, vals in staffs.items():
            qty=vals['qty'] or 0
            amt=vals['amt'] or 0.0
            #state=vals['state']
            categ_id=vals['categ_id']
            report_staff_id=vals['report_staff_id']
            report_staff=get_model("clinic.report.staff").browse(report_staff_id)

            # Find hd case for each staff
            hids=set()
            pids=set()
            for item in get_model("clinic.cycle.item").browse(vals['items']):
                if vals['staff_type']=='nurse':
                    for hd_case in item.hd_cases:
                        #hids.update({hd_case.id})
                        pids.update({hd_case.patient_id.id})
                        #print('pids ', pids)
                else:
                    for hd_case in item.hd_cases:
                        doctor_id=hd_case.doctor_id.id
                        if staff_id==doctor_id:
                            hids.update({hd_case.id})
                            #pids.update({hd_case.patient_id.id})
            rlines=[]
            for hid in list(hids):
                rlines.append(('create',{
                    'hd_case_id': hid,
                    'amount': amt/qty, #XXX
                }))

            plines=[]
            print('pids ', list(pids))
            for pid in list(pids):
                plines.append(('create',{
                    'patient_id': pid,
                }))

            report_staff.write({
                'lines': rlines,
                'patients': plines,
            })
            ##### 

            rate=0.0
            if qty:
                rate=amt/qty # average
            lines.append(('create',{
                'staff_id': staff_id,
                'qty': qty,
                'amount': amt,
                'date': timenow,
                'rate': rate,
                #'state': state,
                'categ_id': categ_id,
                'department_id': vals['department_id'],
                'report_staff_id': report_staff.id,
            }))

        for line in obj.lines:
            line.delete()
        obj.write({
            'lines': lines,
        })

        return {
            'next': {
                'name': 'clinic_labor_cost_entry',
                'mode': 'form',
                'active_id': obj.id,
            },
            'flash': 'Compute Succesffuly',
        }
    
    def create(self,vals,**kw):
        vals['name']=utils.date2thai(vals['date'],format='%(BY)s/%(m)s')
        new_id=super().create(vals,**kw)
        return new_id

    def write(self,ids,vals,**kw):
        if 'date' in vals.keys():
            vals['name']=utils.date2thai(vals['date'],format='%(BY)s/%(m)s')
        else:
            obj=self.browse(ids)[0]
            vals['name']=utils.date2thai(obj.date,format='%(BY)s/%(m)s')
        super().write(ids,vals,**kw)
    
    def update_amount(self,context={}):
        data=context['data']
        total_amt=0.0
        total_damt=0.0
        total_namt=0.0
        for line in data['doctor_lines']:
            total_amt+=line['amount']
            total_damt+=line['amount']
        for line in data['nurse_lines']:
            total_amt+=line['amount']
            total_namt+=line['amount']
        data['total']=total_amt
        data['dcost']=total_damt
        data['ncost']=total_namt
        return data

    def onchange_date(self,context={}):
        data=context['data']
        date=data['date']
        year,month,day=date.split("-")
        weekday, total_day=monthrange(int(year), int(month))
        data['date_from']="%s-%s-01"%(year,month)
        data['date_to']="%s-%s-%s"%(year,month,total_day)
        return data

    def onchange_line(self,context={}):
        data=context['data']
        path=context['path']
        line=get_data_path(data,path,parent=True)
        cmax=line['max_cycle'] or 0
        qty=line['qty'] or 0
        rate=line['rate'] or 0
        over=min(0,cmax-qty)
        print('xx ', cmax, qty, over)
        if cmax<=0:
            over=0
        line['amount']=qty*rate
        line['over_cycle']=over
        data=self.update_amount(context)
        return data
    
    def onchange_branch(self,context={}):
        data=context['data']
        data['department_id']=None
        return data
    
    def approve(self,ids,context={}):
        for obj in self.browse(ids):
            obj.write({
                'state': 'approved',
            })

    def to_draft(self,ids,context={}):
        for obj in self.browse(ids):
            obj.write({
                'state': 'draft',
            })

LaborCostEntry.register()