import time
from calendar import monthrange
from datetime import datetime, timedelta

from netforce.model import Model, fields, get_model
from netforce.access import get_active_company

from . import utils

DRT=0
HD_STATE={
    "draft":"Draft",
    'waiting_treatment':'Waiting Treatment',
    "in_progress":"In Progress",
    "completed":"Finish Treatment",
    'paid':'Paid',
    "waiting_payment":"Waiting Payment",
    "discountinued":"Discountinued",
    "cancelled":"Cancelled"
}
DAYS={
    'mon': 0,
    'tue': 1,
    'wed': 2,
    'thu': 3,
    'fri': 4,
    'sat': 5,
    'sun': 6,
}

class VisitBoard(Model):
    _name="clinic.visit.board"
    _string="Visit Board"
    _transient=True
    _name_field="date" 

    _fields={
        "date": fields.Date("Month", required=False),
        "date_from": fields.Date("From", required=True),
        "date_to": fields.Date("To", required=True),
        'patient_id': fields.Many2One("clinic.patient","Patient",domain=[['state','=','admit']]),
        'cycle_id': fields.Many2One("clinic.cycle","Cycle"),
        'doctor_id': fields.Many2One("clinic.staff","Doctor",domain=[["type","=","doctor"]]),
        'department_id': fields.Many2One("clinic.department","Department"),
        'branch_id': fields.Many2One("clinic.branch","Branch"),
        "state": fields.Selection([["draft","Draft"],['pending','Pending'],["confirmed","Confirmed"],["cancelled","Cancelled"]],"Status",required=True),
    }
    
    def default_get(self,field_names=None,context={},**kw):
        defaults=context.get("defaults",{})
        date=defaults.get('date',time.strftime("%Y-%m-%d"))
        date_from=defaults.get("date_from",time.strftime("%Y-%m-%d"))
        date_to=defaults.get("date_to")
        if not date_to:
            date_to=(datetime.now()+timedelta(days=DRT)).strftime("%Y-%m-%d")
        branch_id=defaults.get("branch_id")
        department_id=defaults.get("department_id")
        res=get_model('select.company').get_select()
        if res:
            if not branch_id:
                branch_id=res['branch_id']
            if not department_id:
                if res.get('department_ids'):
                    department_id=res['department_ids'][0]
                else:
                    department_id=res['department_id']
        res={
            'date': date,
            'date_from': date_from,
            'date_to': date_to,
            'branch_id': branch_id,
            'department_id': department_id,
            'state': 'pending',
        }
        print('clinic.visit.board.defaults ', defaults)
        return res
    
    def get_report_data(self,ids,context={}):
        company_id=get_active_company()
        company=get_model("company").browse(company_id)
        date_from=datetime.now().strftime("%Y-%m-%d")
        date_to=(datetime.now()+timedelta(days=DRT)).strftime("%Y-%m-%d")
        patient_id=None
        cycle_id=None
        doctor_id=None
        defaults=self.default_get(context=context)
        department_id=defaults.get("department_id",None)
        branch_id=defaults.get("branch_id",None)
        state=defaults.get("state",'pending')
        if ids:
            obj=self.browse(ids)[0]
            date_from=obj.date_from
            date_to=obj.date_to
            patient_id=obj.patient_id.id
            cycle_id=obj.cycle_id.id
            doctor_id=obj.doctor_id.id
            department_id=obj.department_id.id
            branch_id=obj.branch_id.id
            state=obj.state
        # auto generate visit day to day
        def auto_gen_visit(dom=[]):
            dom.append(['dispose','=',False])
            def daterange(start_date, end_date):
                for n in range(int ((end_date - start_date).days)):
                    yield start_date + timedelta(n)
            def convert_date(date_txt):
                try:
                    if not date_txt:
                        raise Exception("Date Empty")
                    return datetime.strptime(date_txt,"%Y-%m-%d")
                except:
                    raise Exception("Wrong Format Date")
            # check day of week of this day
            for date in daterange(convert_date(date_from),convert_date(date_to)+timedelta(days=1)):
                weekday=date.weekday()
                date_txt=date.strftime("%Y-%m-%d")
                datenow=time.strftime("%Y-%m-%d")
                if date_txt < datenow:
                    print("continue ", date_txt, datenow)
                    continue
                for pt in get_model("clinic.patient").search_browse(dom):
                    for pc in pt.cycles:
                        w=DAYS.get(pc.day,0) #default monday
                        cycle=pc.cycle_id
                        department=pc.department_id
                        if weekday==w:
                            dom2=[
                                ['visit_date','=',date_txt],
                                ['patient_id','=',pt.id],
                                #['cycle_id','=',cycle.id], #XXX
                                ['department_id','=',department.id],
                            ]
                            res=get_model("clinic.visit").search(dom2)
                            # create visit auto
                            if not res:
                                vals={
                                    'patient_id': pt.id,
                                    'department_id': department.id,
                                    'cycle_id': cycle.id,
                                    'doctor_id': pt.doctor_id.id,
                                    'branch_id': department.branch_id.id,
                                    'time_start': '%s %s:00'%(date_txt,cycle.time_start),
                                    'time_stop': '%s %s:00'%(date_txt,cycle.time_stop),
                                    'visit_date': date_txt,
                                    'state': 'pending',
                                }
                                visit_id=get_model("clinic.visit").create(vals)
                                print('create new visit %s for %s'%(visit_id,pt.name))
        time_start='%s 00:00:00'%(date_from)
        time_stop='%s 23:59:59'%(date_to)
        dom=[]
        dom.append(['time_start','>=','%s'%time_start])
        dom.append(['time_stop','<=','%s'%time_stop])
        if patient_id:
            dom.append(['patient_id','=',patient_id])
        if cycle_id:
            dom.append(['cycle_id','=',cycle_id])
        if doctor_id:
            dom.append(['doctor_id','=',doctor_id])
        if department_id:
            dom.append(['department_id','=',department_id])
        if branch_id:
            dom.append(['branch_id','=',branch_id])
        #gen visit
        if department_id:
            auto_gen_visit(dom=[['department_id','=',department_id]])
        elif branch_id:
            auto_gen_visit(dom=[['branch_id','=',branch_id]])
        lines=[]
        empty_line={
            'no': '',
            'number': '',
            'visit_id': None,
            'visit_state': '',
            'cycle_name': '',
            'cycle_color': '',
            'department_id': None,
            'department_name': None,
            'branch_id': None,
            'branch_name': None,
            'patient_id': None,
            'patient_name': '',
            'patient_type': '',
            'patient_type_id': None,
            'doctor_name': '',
            'doctor_id': None,
            'hd_case_number': '',
            'hd_case_id': None,
            'success_color': '',
            'date':'',
            'title': True,
            'footer': False,
            'details':'',
            'hd_case_state': '',
            'hn': '',
        }
        
        patient_types={t['id']:t['name'] for t in get_model("clinic.patient.type").search_read([[]],['name'])}
        cycle_names={t['id']:t['name'] for t in get_model("clinic.cycle").search_read([[]],['name'])}
        brch_names={t['id']:t['name'] for t in get_model("clinic.branch").search_read([[]],['name'])}
        dpt_names={t['id']:t['name'] for t in get_model("clinic.department").search_read([[]],['name'])}
        total_wait=0
        total_done=0
        total_cancel=0
        types={}
        cycles={}
        no=1
        dpt={}
        brch={}
        if state=='pending':
            dom+=[['state', 'in',[state,'confirmed']]]
        else:
            dom+=[['state', 'in',[state]]]
        print('dom ', dom)
        for visit in get_model("clinic.visit").search_browse(dom):
            if visit.state in ('draft','pending'):
                total_wait+=1
            elif visit.state in ('confirmed'):
                total_done+=1
            else:   
                total_cancel+=1

            hd_case_id=None
            hd_case_number=''
            hd_case_state=''
            visit_color=''
            sickbed_name='N/A'
            sickbed_id=None
            if visit.hd_cases:
                hd_case=visit.hd_cases[0]
                sickbed_name=hd_case.sickbed_id.name or "N/A"
                sickbed_id=hd_case.sickbed_id.id
                hd_case_id=hd_case.id,
                if hd_case.number=='/':
                    hd_case_number='Waiting'
                else:
                    hd_case_number=hd_case.number
                hd_case_state=hd_case.state
                if hd_case_state=='completed':
                    #visit_color='#99ff99'
                    visit_color=''
                elif hd_case_state=='in_progress':
                    #visit_color='#f9e37d'
                    visit_color=''
                elif hd_case_state=='cancelled':
                    visit_color='#dbdbdb',
                    hd_case_number="Cancelled"
            number=visit.number
            if number=='/':
                number='Waiting'
            cycle=visit.cycle_id
            patient=visit.patient_id
            if not patient.active:
                print('skip not active ', patient.name)
                continue
            branch=visit.branch_id
            department=visit.department_id
            if not branch:
                branch=department.branch_id 
           
            hn_name=patient.hn_no or '-'

            visit_date=visit.visit_date
            if visit.state=='cancelled':
                visit_color='#dbdbdb',
                if visit.number=='/':
                    number='Cancelled'
                else:
                    number+='Cancelled'
            line={
                'number': number,
                'hn_name': hn_name,
                'visit_id': visit.id,
                'sickbed_name': sickbed_name,
                'sickbed_id': sickbed_id,
                'cycle_name': cycle.name,
                'cycle_color': cycle.color,
                'department_id': department.id,
                'department_name': department.name or '',
                'branch_id': branch and branch.id or None,
                'branch_name': branch and branch.name or '',
                'patient_name': patient.name,
                'patient_id': patient.id,
                'patient_type': patient.type_id.name or "",
                'patient_type_id': patient.type_id.id or None,
                'doctor_name': visit.doctor_id.name,
                'doctor_id': visit.doctor_id.id,
                'hd_case_number': hd_case_number,
                'hd_case_state': hd_case_state,
                'hd_case_state_txt':HD_STATE.get(hd_case_state,''),
                'hd_case_id': hd_case_id,
                'visit_color':  visit_color,
                'date': visit_date,
                'title': False,
                'footer': False,
                'details':'',
                'details1':'',
                'details2':'',
                'details3':'',
                'details4':'',
                'details5':'',
                'no': no,
                'note': visit.note,
            }
            lines.append(line)
            no+=1
            if not types.get(visit_date):
                ptype={}
                [ptype.setdefault(t,0) for t in patient_types.keys()]
                types[visit_date]=ptype
            types[visit_date][patient.type_id.id]+=1

            if not cycles.get(visit_date):
                cycle_name={}
                [cycle_name.setdefault(cid,0) for cid in cycle_names.keys()]
                cycles[visit_date]=cycle_name
            cycles[visit_date][cycle.id]+=1

            if not brch.get(visit_date):
                brch_name={}
                [brch_name.setdefault(cid,0) for cid in brch_names.keys()]
                brch[visit_date]=brch_name
            brch[visit_date][branch.id]+=1

            if not dpt.get(visit_date):
                dpt_name={}
                [dpt_name.setdefault(cid,0) for cid in dpt_names.keys()]
                dpt[visit_date]=dpt_name
            dpt[visit_date][department.id]+=1
        
        dates=[]
        index=0
        total_qty=0
        count=0
        for line in lines:
            date=line['date']
            if not date:
                continue
            if date not in dates:
                count=0
                total_qty=0
                line=empty_line.copy()
                for qty in types[date].values():
                    total_qty+=qty
                line['cycle_name']=utils.date2thai(date,format='%(Td)s %(d)s %(Tm)s',lang="th_TH2"),
                lines.insert(index,line)
                dates.append(date)
            if count==total_qty and not patient_id:
                index+=1
                # footer
                line=empty_line.copy()
                patient_str='%s'%', '.join('%s: %s'%(patient_types[k],v) for k,v in types[date].items())
                cycle_str='%s'%', '.join('%s: %s'%(cycle_names[k],v) for k,v in cycles[date].items())
                brch_str='%s'%', '.join('%s: %s'%(brch_names[k],v) for k,v in brch[date].items())
                dpt_str='%s'%', '.join('%s: %s'%(dpt_names[k],v) for k,v in dpt[date].items())
                summary_str='%s'%', '.join(['รับไว้: %s'%total_wait,'จำหน่ายแล้ว: %s'%total_done, 'ยกเลิก: %s'%total_cancel])
                line['details']='ทั้งหมด %s:  %s'%(total_qty,', '.join([summary_str,cycle_str,patient_str]))
                line['details1']=brch_str
                line['details2']=summary_str
                line['details3']=cycle_str
                line['details4']=patient_str
                line['details5']=dpt_str
                line['footer']=True
                line['title']=False
                lines.insert(index,line)
            count+=1
            index+=1

        has_duration=False
        if date_from != date_to:
            has_duration=True
        data={
            'lines': lines,
            'date': utils.date2thai(date_from,format='ประจำวัน%(Td)s ที่ %(d)s %(Tm)s %(BY)s'),
            'company_name': company.name,
            'company_parent_name': company.parent_id.name,
            'has_duration': has_duration,
            'date_from': utils.date2thai(date_from,format='%(d)s %(Tm)s %(By)s',lang="th_TH2"),
            'date_to': utils.date2thai(date_to,format='%(d)s %(Tm)s %(By)s',lang="th_TH2"),
        }
        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_datefrom(self,context={}):
        data=context['data']
        data['date_to']=data['date_from']
        return data

    def onchange_branch(self,context={}):
        data=context['data']
        data['department_id']=None
        return data

    def confirm(self,ids,context={}):
        obj=self.browse(ids)[0]
        return {
            'next': {
                'refer_id': obj.id,
                'name': 'clinic_popup_visit_confirm',
            }
        }

VisitBoard.register()