import time

from netforce.model import Model, fields, get_model
from netforce.utils import get_file_path

class MatchingHDCase(Model):
    _name="clinic.matching.hdcase"
    _transient=True

    _fields={
        "date_from": fields.Date("From", required=True),
        "date_to": fields.Date("To", required=True),
        'file': fields.File("File"),
        'state': fields.Selection([["match","Math"],["not_match","Not Match"]],"State"),
        'skip_lines': fields.One2Many("clinic.matching.hdcase.line","matching_hdcase_id","Skip Lines"),
        'file_lines': fields.One2Many("clinic.matching.hdcase.file","matching_hdcase_id","File Lines"),
        'msg': fields.Text("Message"),
        'branch_id': fields.Many2One("clinic.branch","Branch"),
    }
    
    def _get_skip_lines(self,context={}):
        skip_lines=[]
        st=get_model('clinic.setting').browse(1)
        if st.skip_type_id:
            skip_lines.append({
                'type_id': st.skip_type_id.id,
            })
        return skip_lines

    _defaults={
        'date_from': lambda *a: time.strftime('%Y-%m-%d'),
        'date_to': lambda *a: time.strftime('%Y-%m-%d'),
        'skip_lines': _get_skip_lines,
    }
    
    def get_rows(self,fpath=None):
        if not fpath:
            raise Exception("File not found")
        try:
            # or codecs.open on Python 2
            filedata = open(fpath, encoding='UTF-8').read() 
        except:
            filedata = open(fpath, encoding='TIS-620').read() 
        lines=filedata.split("\n")
        count=0
        rows=[]
        for line in lines:
            #open
            if '***' in line and count==0:
                count+=1
            #end    
            elif '***' in line and count==1:
                count=0

            #table content
            if count==1:
                line=line.replace("*","")
                line=line.replace("|","")
                i=0
                vals={}
                for l in line.split(","):
                    if l:
                        vals[i]=l  
                        i+=1
                # only right data
                if vals:
                    if len(vals)>1:
                        rows.append(vals)
        return rows

    def get_report_data(self,ids,context={}):
        defaults=self.default_get(context=context)
        date_from=defaults.get("date_from")
        date_to=defaults.get("date_to")
        branch_id=defaults.get("branch_id")
        lines=[]
        state="all"
        if ids:
            obj=self.browse(ids)[0]
            state=obj.state or "all"
            date_from=obj.date_from
            date_to=obj.date_to
            branch_id=obj.branch_id.id
            skip_lines=[skip.type_id.name for skip in obj.skip_lines]
            if not obj.file:
                return {}
            fpath=get_file_path(obj.file)
            rows=self.get_rows(fpath)
            if not rows:
                return {
                    'message': 'No Data',
                }
            #{0: ' A 01',
             #1: ' 6',
             #2: ' 11686',
             #3: ' 91312851',
             #4: ' 450124497',
             #5: ' 27/01/2558 06:05:00',
             #6: ' C',
             #7: ' O',
             #8: ' U ',
             #9: ' N',
             #10: ' Espogen',
             #11: '       4000',
             #12: '         30',
             #13: '          1',
             #14: '          0',
             #15: '       1500',
             #16: '       1500',
             #17: ' 0',
             #18: '       1500',
             #19: ' S',
             #20: ' U '}

            patients={}
            dom=[
                ['dispose','=',False],
                ['walkin','=','no'],
            ]
            for pt in get_model("clinic.patient").search_read(dom,['name','hn_no','type_id']):
                hn=pt['hn_no']
                patients[hn]={
                    'id': pt['id'],
                    'name': pt['name'] or '',
                    'type': pt['type_id'][1],
                }
            products={}
            for prod in get_model("product").search_read([],['name']):
                name=(prod['name'] or "").replace(" ", "")
                name=name.upper()
                products[name]=prod['id']
            dom=[]
            dom.append(['patient_id.walkin',"=","no"]) #XXX
            dom.append(['date',">=",date_from])
            dom.append(['date',"<=",date_to])
            dom.append(['state','!=','cancelled'])
            if branch_id:
                dom.append(['branch_id','=',branch_id])
            hdcases1={}
            hdcases2={}
            hdcases3={}
            def get_account_patient_hn(patient_id):
                res=get_model("clinic.setting.account.patient").search_read([['patient_id','=',patient_id]],['hn','patient_id'])
                if res:
                    return res[0]
                return res
            print('hdcase get key ....')
            for hdcase in get_model("clinic.hd.case").search_browse(dom):
                date=hdcase.date
                hn=hdcase.patient_id.hn_no or ""
                fee_amt=0
                hct=hdcase.hct or "0"
                hct=round(float(hct),2)
                prod_line=[]
                for line in hdcase.lines:
                    prod=line.product_id 
                    categ=prod.categ_id
                    if categ and line.reimbursable=='yes':
                        if categ.code=='EPO':
                            prod_name=(prod.name or "").split("-")
                            if len(prod_name) >= 1:
                                prod_name=prod_name[0]
                            prod_line.append(prod_name)
                        elif categ.code=='FEE':
                            fee_amt=line.amount or 0
                prod_name=''
                if prod_line:
                    prod_name='-'.join(prod_line)
                key1='%s-%s-%s-%s'%(date,hn,prod_name,fee_amt)
                hdcases1[key1]={
                    'id': hdcase.id,
                    'number': hdcase.number or '',
                    'note': '',
                }
                key2='%s-%s'%(date,hn)
                hdcases2[key2]={
                    'id': hdcase.id,
                    'number': hdcase.number or '',
                    'note': '%s, %s, %s, %s, %s'%(date,hn,hct,prod_name,fee_amt),
                }
                patient=hdcase.patient_id
                result=get_account_patient_hn(patient.id)
                if result:
                    hn=result['hn']
                    key3='%s-%s-%s-%s'%(date,hn,prod_name,fee_amt)
                    hdcases3[key3]={
                        'id': hdcase.id,
                        'number': hdcase.number or '',
                        'note': '',
                        'patient_id': patient.id,
                        'patient_name': patient.name,
                        'patient_type': patient.type_id.name,
                    }
            ddate=set()
            print('match hdcase ....')
            for row in rows:
                vals=list(row.values())
                date,_time=(vals[5] or "").split()
                ddate.update({date})
                if len(date)<3:
                    raise Exception("Wrong format date")
                d,m,y=date.split("/")
                y=int(y)-543
                date='%s-%s-%s'%(y,m,d)
                hn=vals[3]
                hn=''.join(x for x in (hn or "") if x.isdigit())
                pt=patients.get(hn)
                pt_type=''
                pt_name=''
                pt_id=None
                if pt:
                    pt_name=pt['name']
                    pt_id=pt['id']
                    pt_type=pt['type']
                hct=float(vals[12] or "0")
                hct=round(hct,2)
                fee_amt=float(vals[15] or "0")
                fee_amt=round(fee_amt,2)
                prod_name=vals[10] or ''
                prod_name=prod_name.replace(" ", "")
                prod_id=products.get(prod_name.upper(),None)
                key1='%s-%s-%s-%s'%(date,hn,prod_name.upper(),fee_amt)
                hdcase=hdcases1.get(key1)
                unit_amt=float(vals[11])
                line_vals={
                    'hn': hn,
                    'date': date,
                    'patient_name': pt_name,
                    'patient_id': pt_id,
                    'patient_type': pt_type,
                    'hct': hct,
                    'prod_name': (prod_name or "").title(), 
                    'prod_id': prod_id,
                    'fee_amt': fee_amt,
                    'note': '',
                    'nf_date': '',
                    'nf_hn': '',
                    'nf_hct': '',
                    'nf_epo': '',
                    'nf_fee': '',
                    'unit_amt': unit_amt,
                }
                if hdcase:
                    line_vals['is_match']=True
                    line_vals['hd_case_id']=hdcase['id']
                    line_vals['hd_case_number']=hdcase['number']
                else:
                    line_vals['is_match']=False
                    
                key2='%s-%s'%(date,hn)
                hdcase2=hdcases2.get(key2)
                if hdcase2:
                    line_vals['hd_case_id']=hdcase2['id']
                    line_vals['hd_case_number']=hdcase2['number']
                    line_vals['note']=''
                    nf_date,nf_hn,nf_hct,nf_epo,nf_fee=hdcase2['note'].split(",")
                    line_vals['nf_date']=nf_date
                    line_vals['nf_hn']=nf_hn
                    line_vals['nf_hct']=nf_hct
                    nf_epo=(nf_epo or "").replace("-",",")
                    line_vals['nf_epo']=nf_epo.title()
                    line_vals['nf_fee']=round(float((nf_fee or "0")),2)
                lines.append(line_vals)

                key3='%s-%s-%s-%s'%(date,hn,prod_name.upper(),fee_amt)
                hdcase=hdcases3.get(key3)
                if hdcase:
                    line_vals['is_match']=True
                    line_vals['hd_case_id']=hdcase['id']
                    line_vals['hd_case_number']=hdcase['number']
                    line_vals['patient_id']=hdcase['patient_id']
                    line_vals['patient_name']=hdcase['patient_name']
                    line_vals['patient_type']=hdcase['patient_type']
        no=1
        lines2=[]
        total=0
        total_match=0
        total_unmatch=0
        mdate=[]
        print('sorted line ...')
        for line in sorted(lines,key=lambda x: x['hn']):
            ldate=line.get('date') or ""
            if ldate not in mdate:
                mdate.append(ldate)
            cont=ldate and (ldate >=date_from and ldate <= date_to)
            # skip out of range
            if not cont:
                continue 
            patient_type=line.get('patient_type')
            hn=line.get('hn')
            if patient_type in skip_lines:
                print('continue ', patient_type)
                continue
            elif not patient_type and hn:
                found=0
                for pt in get_model("clinic.patient").search_browse([['hn_no','=',hn]]):
                    if pt.type_id.name in skip_lines:
                        found=1
                        break
                if found:
                    print('continue ', hn)
                    continue
            is_match=line.get('is_match',False)
            if is_match:
                total_match+=1
            else:
                total_unmatch+=1
            total+=1
            if state=='not_match' and is_match:
                continue
            elif state=='match' and not is_match:
                continue
            else:
                pass
            line['no']=no
            lines2.append(line)
            no+=1
        lines=lines2
        date=''
        if date_from==date_to:
            date=date_from
        nlines=[]
        no=1
        for line in sorted(lines,key=lambda x: x.get('date')):
            line['no']=no
            nlines.append(line)
            no+=1
        data={
            'state': state,
            'lines': nlines,
            'date_from': date_from,
            'date_to': date_to,
            'date': date,
            'total': total,
            'total_match': total_match,
            'total_unmatch': total_unmatch,
            'message': '',
        }
        if no <=1 and ids:
            data['message']="%s"%', '.join(sorted(ddate)) 
        return data

    def onchange_date(self,context={}):
        data=context['data']
        data['date_to']=data['date_from']
        return data

MatchingHDCase.register()