import logging
from dbmodel import *
import hl7
from hl7.client import MLLPClient
import datetime
import time
from pydicom.uid import generate_uid

LOGGER = logging.getLogger('sampacs')
SEP = '\r|^~\&'
CR_SEP = '\r'

def main():
    kometa = config.kometa
    samson_db.connect()
    try:
        stmt = """ SELECT
                    c.lastName AS lastName,
                    c.firstName AS firstName,
                    c.patrname AS patrName,
                    c.id AS clientId,
                    c.birthDate AS birthDate,
                    CASE c.sex
                        WHEN 1 THEN 'M'
                        WHEN 2 THEN 'F'
                        ELSE 'U'
                    END AS sex,
                    c.SNILS AS snils,
                    eq.labCode AS aet,
                    a.id AS actionId,
                    a.begDate AS actionBegDate,
                    at.name AS actionName,
                    at.code AS actionCode,
                    Job_Ticket.dateTime as ticketDate,
                    eq.labCode,
                    eq.labName,
                    p.lastName,
                    p.firstName,
                    p.patrName,
                    p.id
                FROM
                    Action AS a
                        LEFT JOIN
                    ActionProperty ON ActionProperty.action_id = a.id
                        LEFT JOIN
                    ActionProperty_Job_Ticket ON ActionProperty_Job_Ticket.id = ActionProperty.id
                        LEFT JOIN
                    Job_Ticket ON Job_Ticket.id = ActionProperty_Job_Ticket.value
                        INNER JOIN
                    ActionType AS at ON at.id = a.actionType_id
                        INNER JOIN
                    Event AS e ON e.id = a.event_id
                        INNER JOIN
                    Client AS c ON c.id = e.client_id
                        INNER JOIN
                    ActionType_Equipment AS ate ON ate.master_id = at.id
                        INNER JOIN
                    rbEquipment AS eq ON eq.id = ate.equipment_id
                        INNER JOIN
                    Person as p on p.id = a.setPerson_id
                WHERE
                        (a.status = 0 OR a.status = 5)
                        AND c.SNILS != ''
                        AND a.deleted = 0
                        AND ActionProperty_Job_Ticket.value IS NOT NULL
                        AND eq.labCode != ''
                        AND eq.labName != ''
                        AND a.begDate > date_sub(NOW(), INTERVAL 11 DAY)
                ORDER BY c.lastName
                """
        cursor = samson_db.execute_sql(stmt)

        resultList = []

        for r in cursor.fetchall():
            lastName = r[0]
            firstName = r[1]
            patrName = r[2]
            clientId = r[3]
            birthDate = r[4]
            sex = r[5]
            snils = r[6]
            aet = r[7]
            actionId = r[8]
            aBegDate = r[9]
            actionName = r[10]
            actionCode = r[11]
            ticketDate = r[12]
            modality = r[13]
            aetitle = r[14]
            plastName = r[15]
            pfirstName = r[16]
            ppatrName = r[17]
            pid = r[18]
            MSH = createHeader('ORM^O01')
            PID = createSegment('PID')
            ORC = createSegment('ORC')
            OBR = createSegment('OBR')
            ZDS = createSegment('ZDS')
            message = hl7.Message(CR_SEP, [MSH, PID, ORC, OBR, ZDS])
            message['PID.F3'] = snils if kometa.snilsAsId else str(clientId)
            message['PID.F5.R1'] = lastName
            message['PID.F5.R2'] = firstName
            message['PID.F5.R3'] = patrName
            message['PID.F7'] = birthDate.strftime("%Y%m%d")
            message['PID.F8'] = sex

            message['ORC.F1'] = 'NW'
            message['ORC.F2'] = str(actionId)
            message['ORC.F9'] = ticketDate.strftime("%Y%m%d%H%M")
            message['ORC.F12.R1'] = str(pid)
            message['ORC.F12.R2'] = plastName
            message['ORC.F12.R3'] = pfirstName
            message['ORC.F12.R4'] = ppatrName
            message['ORC.F18'] = aetitle

            message['OBR.F2'] = str(actionId)
            message['OBR.F4'] = actionName
            message['OBR.F18'] = str(actionId)
            message['OBR.F19'] = kometa.orgCode
            message['OBR.F24'] = modality

            message['ZDS.F1'] = generate_uid()

            LOGGER.debug('KOMETA   %s'%str(message).replace('\r', '\n'))

            with MLLPClient(kometa.host, kometa.port) as client:
                ans = client.send_message(message)
                ansmsg = hl7.parse(ans)
                LOGGER.debug('KOMETA   %s'%str(ansmsg).replace('\r', '\n'))
                if ansmsg and ansmsg[0][9][0] == 'ACK':
                    if ansmsg[1][1][0] == 'AA':
                        query = Action.update(status=1).where(Action.id == actionId)
                        query.execute()
                    else:
                        LOGGER.error('KOMETA   %s'%ansmsg[1][3][0])

                print(ans)
    finally:
        samson_db.close()

def createHeader(msgType):
    return hl7.Segment(SEP[1], ['MSH',
                                SEP[1],
                                SEP[2:],
                                'SAMSON',
                                '',
                                'KOMETA',
                                '',
                                str(datetime.datetime.now().strftime("%Y%m%d%H%M%S")),
                                '',
                                msgType,
                                hl7.generate_message_control_id(),
                                'D',
                                '2.5',
                                '',
                                '',
                                'AL',
                                'AL',
                                '',
                                'UNICODE UTF-8'
                                ])

def createSegment(name):
    return hl7.Segment(SEP[1], [hl7.Field(SEP[2], [name], separators=SEP)], separators=SEP)

def thread_kometa_send():
    LOGGER.info('start kometa server')
    while True:
        try:
            main()
        except AssertionError as e:
            LOGGER.error('assertion error')
        except Exception as e:
            LOGGER.error(e)
        time.sleep(90)

if __name__ == "__main__":
    kometa = config.kometa
    #pwlog = logging.getLogger('peewee')
    #pwlog.addHandler(logging.StreamHandler())
    #pwlog.setLevel(logging.DEBUG)
    if kometa.host:
        thread_kometa_send()