from .common import X12DOCUMENT
from .header import HEADER
import numpy as np


class BODY (HEADER):
    """
    This class will contain functions that will parse elements associated with the claim body
    """
    def BHT (self,**_args):
        """
        Expected Element BHT
        This functiion will process header submitted (receiver,claim_type,)
        """
        _columns= ['receiver_id','submitted_date','submitted_time','claim_type']
        return self.parse(_columns,[3,7],**_args)
       
    def NM1 (self,**_args):
        """
        Expected Element NM1
        ref IL,40,41,82,85,PR ...
        Information about entities (doctors, clearing house, provider). we should be mindful of the references
        """
        _CODE_INDEX = 1
        CONTEXT_MAP = {
            
                '2':{'field':'payer'},
                'PR':{'field':'payer'},
                '41':{'field':'header'},
                'IL':{'field':'patient','map':{'type':2,'first_name':4,'last_name':3}},
                'P5':{'field':'plan_sponsor'},
                '82':{'field':'rendering_provider','map':{'type':2,'first_name':4,'last_name':3}},
                '85':{'field':'billing_provider'}
            
        }
        _args ['plugin-context'] = {'@ref':CONTEXT_MAP}
        # _map = {_CODE_INDEX:{'41':'submitter','40':'receiver','PR':'payer'}} 
        _columns = ['type','name','id']  
        _indexes = [1,3,-1]    
        # _info = [{'index':'40','field':'receiver'},{'index':'41','field':'submitter'},{'index':'PR','field':'payer'}]
        
        _info =  self.parse(_columns,_indexes,**_args)    
        self.lastelement = _info
        return _info
    def N3 (self,**_args):
        """        
        Expected Element N3
        """
        
        _columns = ['address_line_1']
        return self.parse(_columns,[1,2],**_args)
    
    def N4(self,**_args):
        """
        Expected Element N4
        """
        _columns = ['city','state','zip']
        return self.parse(_columns,[1,2,3],**_args)
    def HI(self,**_args):
        """
        Expected Element HI
        This function will parse diagnosis codes ICD 9/10
        """
        _columns = ['code','type']
        return self.parse(_columns,[2,1],**_args)
    def AMT (self,**_args):
        """
        Expected Element AMT
        """
        _columns = ['amount','qualifier']
        return self.parse(_columns,[2,1],**_args)
    def SBR (self,**_args):
        """
        Expected Element SBR
        """
        _index = [9,1]
        _columns = ['vendor','individual_code','type']
        return self.parse(_columns,[9,2,1],**_args)
    def DMG (self,**_args):
        """
        Expected Element DMG
        """
        _columns    = ['dob','gender','format']
        _info  = self.parse(_columns,[2,3,1],**_args)

        return _info
    def DTP (self,**_args):
        """
        Expected Element DTP
        """
        _columns = ['to','from','type']
        return self.parse(_columns,[3],**_args)
    def PER (self,**_args):
        """
        Expected Element PER
        """
        _CODE_INDEX = 1
        _map = {_CODE_INDEX:{'IC':'submitter'}}  # attribute to store the data in
        _columns = ['contact_name','phone','email']
        _info =  self.parse (_columns,[2,4,8],**_args)
       #
       # @TODO: Inspect the configuration file for the attribute information
       #        
        return _info
    def CLM (self,**_args):
        """
        Expected Element CLM
        """
        _columns = ['claim_id','claim_amount','facility_code','facility_qualifier','frequency_code']
        return self.parse(_columns,[1,2,5,5,5],**_args)
    def REF (self,**_args):
        _columns = ['identifier','qualifier','']
        _CODE_INDEX = 1 # -- according to x12 standard
        _map = {_CODE_INDEX:{'EA':'patient','EI':'provider','6R':'','D9':''}}
        return self.parse(_columns,[2],**_args)
          
    def HI (self,**_args):
        """
        Expected Element HI
        """
        _columns = ['code','type']
        return self.parse(_columns,[1,2],**_args)
    def SV1 (self,**_args):
        """
        Expected Element SV1
        """
        _row = _args['row'] if type(_args['row']) == list else _args['row'].split('*')
        _columns = ['type','code','amount','modifier_1','modifier_2','modifier_3','modifier_4','place_of_service','units','measurement']
        return self.parse(_columns,[1,1,2,1,1,1,1,5,4,3],**_args)
    
    def SV3 (self,**_args):
        return self.SV1(**_args)
    def HL (self,**_args) :
        """,
        Expected Element HL
        The expected block is supposed to be unprocessed (to make things simple)
        """
        _row    = _args['row'] if type(_args['row']) == list else _args['row'].split('~')
        
        # _attr = self.elements() #[_name for _name in dir() if not _name.islower() and not _name.startswith('_')]
        # _pointers = [getattr(self,_name) for _name in _attr]
        # _map = dict(zip(_attr,_pointers))
        _map = self.pointers()
        
        #
        # The index here tells us what we are processing i.e index == 1 something about header
        #
        _columns = ['_index','parent','code','child']
        _args['row'] = _row[0]
        
        _info =  self.parse (_columns,[1,2,3,4],**_args)
        # _field = 'billing_provider' if _info['_index'] == '1' else 'patient'
        # _config ={'field':_field}
        return _info
        # _claim  = {_field:_info}
        # for _element in _row[1:] :
        #     _key = _element.split('*')[0]
        #     if _key in _map  and len(_element) > 0:
        #         _document = _args['document']
        #         _pointer = _map[_key]
        #         if _key not in ['CLM','HI','SV3','SV2','SV1'] :
        #             _claim = self.merge (_claim,_pointer(row=_element.strip().split('*'),document=_document,config=_config))
        #         else:
        #             _config = _args['config'] if 'config' in _args else {}
        #             _claim = self.merge (_claim,_pointer(row=_element.strip().split('*'),document=_document,config=_config))
        #     else:
        #         print (['SKIPPING ',_key])
        #         pass
            
        # return _claim    
    # def apply(self,_block):
    #     """
    #     :_block elements that do not belong to the header block
    #     """
    #     _apply = self.pointers()
        
    #     _header = {}
    #     if _block :
            
    #         for content in _block :
                
    #             _KEY_ELEMENT = content.split('*')[0]
    #             if _KEY_ELEMENT not in _apply :
    #                 #
    #                 # @TODO: Log elements that are skipped
    #                 # print ([_KEY_ELEMENT , 'NOT FOUND'])
    #                 continue
                
    #             _info   = _apply[_KEY_ELEMENT](row=content,document=_header)
                
    #             if _info :
    #                 if not _header :
    #                     _header = _info
                        
    #                 else:
                        
    #                     _header = self.merge(_header,_info)
    #             else:
    #                 #
    #                 # For some reason the parser failed by returning a null
    #                 # @TODO: Log this event ....
    #                 pass
    #     else:
    #         #
    #         # @TODO: return the meta data for what is expected
    #         pass
    #     return _header