#  mygh_import_readings.py
#
#  Copyright 2023 Luis Falcon <falcon@gnuhealth.org>
#  Copyright 2023 GNU Solidario <health@gnusolidario.org>
#
#  This program is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation; either version 3 of the License, or
#  (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software
#  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
#  MA 02110-1301, USA.
#
#

import csv
import sys
import datetime
from uuid import uuid4
from tinydb import TinyDB
from mygnuhealth.myghconf import dbfile
db = TinyDB(dbfile)


def save_values(table, vals):
    """
        Insert the record on the appropriate table
    """
    dbtable = db.table(table)
    print("Inserting into DB", dbtable, vals)
    dbtable.insert(vals)

    print("Saved event", vals)


def set_weight(vals):
    """
        Validate weight (kg) and set the value
    """
    weight = vals['weight']
    height = 0
    if vals['height']:
        height = int(vals['height'])

    if 20 <= weight <= 300:
        # If the height is included, calculate the BMI
        if height in range(60, 250):
            bmi = weight / ((height / 100)**2)
            bmi = round(bmi, 1)  # Use one decimal
            vals['bmi'] = bmi

        save_values('weight', vals)


def set_bp(vals):
    """
        Validate sanity of BP readings
    """
    systolic = vals['systolic']
    diastolic = vals['diastolic']

    if systolic in range(40, 300) and diastolic in range(30, 200):
        save_values('bloodpressure', vals)


def set_hr(vals):
    """
        Validate sanity of HR readings
    """
    hr = vals['heart_rate']
    if hr in range(20, 300):
        save_values('heart_rate', vals)


def validate_date(vdate, vtime):
    """
    Validate the given date and time and return ISO formated value
    """
    date_string = f"{vdate} {vtime}"
    try:
        stodate = datetime.datetime.strptime(date_string,
                                             '%Y-%m-%d %H:%M').isoformat()
    except BaseException:
        print("Error on the date or time. Skipping...")

    return (stodate)


def parse_values():
    """ Check input file validity """
    csv_file = csv.reader(open(sys.argv[1], 'r'))
    csv_file.__next__()  # Skip header
    line_count = 1

    for line in csv_file:
        if not line:  # Skip empty lines
            print("Empty line, skipping...")
            continue
        line_count = line_count + 1
        vdate = line[0]
        vtime = line[1]
        weight = line[2]
        height = line[3]
        bp_sys = line[4]
        bp_dia = line[5]
        heart_rate = line[6]
        # osat = line[7]
        # glucose = line[8]
        # steps = line[9]
        # calories = line[10]
        # sleep = line[11]

        event_id = str(uuid4())

        if vdate:
            if not vtime:   # Set the time to 00:00 when empty
                vtime = "00:00"
            isodate = validate_date(vdate, vtime)

            if weight:
                if height:
                    height = int(height)
                set_weight({'timestamp': isodate,
                            'event_id': event_id,
                            'height': height,
                            'weight': float(weight)})

            # At this point, we'll record the BP when both
            # systolic and diastolic readings are present
            if bp_sys and bp_dia:
                set_bp({'timestamp': isodate,
                        'event_id': event_id,
                        'systolic': int(bp_sys),
                        'diastolic': int(bp_dia)})

            if heart_rate:
                set_hr({'timestamp': isodate,
                        'event_id': event_id,
                        'heart_rate': int(heart_rate)})
        else:
            print("Error in date: Skipping line ", line_count)


if len(sys.argv) < 2:
    sys.exit("You need to specify a CSV file with the results")

print("Checking integrity of the datafile ...")
parse_values()
