# -*- coding: utf-8 -*-
# Copyright (c) 2018, earthians and contributors
# For license information, please see license.txt

from __future__ import unicode_literals
import frappe
import datetime
from frappe import _
import math
from frappe.utils import time_diff_in_hours, rounded
from erpnext.healthcare.doctype.healthcare_settings.healthcare_settings import get_income_account
from erpnext.healthcare.doctype.patient_appointment.patient_appointment import validity_exists
from erpnext.healthcare.doctype.fee_validity.fee_validity import create_fee_validity, update_fee_validity
from erpnext.healthcare.doctype.lab_test.lab_test import create_multiple

@frappe.whitelist()
def get_healthcare_services_to_invoice(patient):
	patient = frappe.get_doc("Patient", patient)
	if patient:
		if patient.customer:
			item_to_invoice = []
			patient_appointments = frappe.get_list("Patient Appointment",{'patient': patient.name, 'invoiced': False},
			order_by="appointment_date")
			if patient_appointments:
				fee_validity_details = []
				valid_days = frappe.db.get_value("Healthcare Settings", None, "valid_days")
				max_visit = frappe.db.get_value("Healthcare Settings", None, "max_visit")
				for patient_appointment in patient_appointments:
					patient_appointment_obj = frappe.get_doc("Patient Appointment", patient_appointment['name'])

					if patient_appointment_obj.procedure_template:
						if frappe.db.get_value("Clinical Procedure Template", patient_appointment_obj.procedure_template, "is_billable") == 1:
							item_to_invoice.append({'reference_type': 'Patient Appointment', 'reference_name': patient_appointment_obj.name, 'service': patient_appointment_obj.procedure_template})
					else:
						practitioner_exist_in_list = False
						skip_invoice = False
						if fee_validity_details:
							for validity in fee_validity_details:
								if validity['practitioner'] == patient_appointment_obj.practitioner:
									practitioner_exist_in_list = True
									if validity['valid_till'] >= patient_appointment_obj.appointment_date:
										validity['visits'] = validity['visits']+1
										if int(max_visit) > validity['visits']:
											skip_invoice = True
									if not skip_invoice:
										validity['visits'] = 1
										validity['valid_till'] = patient_appointment_obj.appointment_date + datetime.timedelta(days=int(valid_days))
						if not practitioner_exist_in_list:
							valid_till = patient_appointment_obj.appointment_date + datetime.timedelta(days=int(valid_days))
							visits = 0
							validity_exist = validity_exists(patient_appointment_obj.practitioner, patient_appointment_obj.patient)
							if validity_exist:
								fee_validity = frappe.get_doc("Fee Validity", validity_exist[0][0])
								valid_till = fee_validity.valid_till
								visits = fee_validity.visited
							fee_validity_details.append({'practitioner': patient_appointment_obj.practitioner,
							'valid_till': valid_till, 'visits': visits})

						if not skip_invoice:
							practitioner_charge = 0
							income_account = None
							service_item = None
							if patient_appointment_obj.practitioner:
								service_item, practitioner_charge = service_item_and_practitioner_charge(patient_appointment_obj)
								income_account = get_income_account(patient_appointment_obj.practitioner, patient_appointment_obj.company)
							item_to_invoice.append({'reference_type': 'Patient Appointment', 'reference_name': patient_appointment_obj.name,
							'service': service_item, 'rate': practitioner_charge,
							'income_account': income_account})

			encounters = frappe.get_list("Patient Encounter", {'patient': patient.name, 'invoiced': False, 'docstatus': 1})
			if encounters:
				for encounter in encounters:
					encounter_obj = frappe.get_doc("Patient Encounter", encounter['name'])
					if not encounter_obj.appointment:
						practitioner_charge = 0
						income_account = None
						service_item = None
						if encounter_obj.practitioner:
							service_item, practitioner_charge = service_item_and_practitioner_charge(encounter_obj)
							income_account = get_income_account(encounter_obj.practitioner, encounter_obj.company)

						item_to_invoice.append({'reference_type': 'Patient Encounter', 'reference_name': encounter_obj.name,
						'service': service_item, 'rate': practitioner_charge,
						'income_account': income_account})

			lab_tests = frappe.get_list("Lab Test", {'patient': patient.name, 'invoiced': False})
			if lab_tests:
				for lab_test in lab_tests:
					lab_test_obj = frappe.get_doc("Lab Test", lab_test['name'])
					if frappe.db.get_value("Lab Test Template", lab_test_obj.template, "is_billable") == 1:
						item_to_invoice.append({'reference_type': 'Lab Test', 'reference_name': lab_test_obj.name,
						'service': frappe.db.get_value("Lab Test Template", lab_test_obj.template, "item")})

			lab_rxs = frappe.db.sql("""select lp.name from `tabPatient Encounter` et, `tabLab Prescription` lp
			where et.patient=%s and lp.parent=et.name and lp.test_created=0 and lp.invoiced=0 and et.docstatus = 1""", (patient.name))
			if lab_rxs:
				for lab_rx in lab_rxs:
					rx_obj = frappe.get_doc("Lab Prescription", lab_rx[0])
					if rx_obj.test_code and (frappe.db.get_value("Lab Test Template", rx_obj.test_code, "is_billable") == 1):
						item_to_invoice.append({'reference_type': 'Lab Prescription', 'reference_name': rx_obj.name,
						'service': frappe.db.get_value("Lab Test Template", rx_obj.test_code, "item")})

			procedures = frappe.get_list("Clinical Procedure", {'patient': patient.name, 'invoiced': False})
			if procedures:
				for procedure in procedures:
					procedure_obj = frappe.get_doc("Clinical Procedure", procedure['name'])
					if not procedure_obj.appointment:
						if procedure_obj.procedure_template and (frappe.db.get_value("Clinical Procedure Template", procedure_obj.procedure_template, "is_billable") == 1):
							item_to_invoice.append({'reference_type': 'Clinical Procedure', 'reference_name': procedure_obj.name,
							'service': frappe.db.get_value("Clinical Procedure Template", procedure_obj.procedure_template, "item")})

			procedure_rxs = frappe.db.sql("""select pp.name from `tabPatient Encounter` et,
			`tabProcedure Prescription` pp where et.patient=%s and pp.parent=et.name and
			pp.procedure_created=0 and pp.invoiced=0 and pp.appointment_booked=0""", (patient.name))
			if procedure_rxs:
				for procedure_rx in procedure_rxs:
					rx_obj = frappe.get_doc("Procedure Prescription", procedure_rx[0])
					if frappe.db.get_value("Clinical Procedure Template", rx_obj.procedure, "is_billable") == 1:
						item_to_invoice.append({'reference_type': 'Procedure Prescription', 'reference_name': rx_obj.name,
						'service': frappe.db.get_value("Clinical Procedure Template", rx_obj.procedure, "item")})

			procedures = frappe.get_list("Clinical Procedure",
			{'patient': patient.name, 'invoice_separately_as_consumables': True, 'consumption_invoiced': False,
			'consume_stock': True, 'status': 'Completed'})
			if procedures:
				service_item = get_healthcare_service_item('clinical_procedure_consumable_item')
				if not service_item:
					msg = _(("Please Configure {0} in ").format("Clinical Procedure Consumable Item") \
						+ """<b><a href="#Form/Healthcare Settings">Healthcare Settings</a></b>""")
					frappe.throw(msg)
				for procedure in procedures:
					procedure_obj = frappe.get_doc("Clinical Procedure", procedure['name'])
					item_to_invoice.append({'reference_type': 'Clinical Procedure', 'reference_name': procedure_obj.name,
					'service': service_item, 'rate': procedure_obj.consumable_total_amount, 'description': procedure_obj.consumption_details})

			inpatient_services = frappe.db.sql("""select io.name, io.parent from `tabInpatient Record` ip,
			`tabInpatient Occupancy` io where ip.patient=%s and io.parent=ip.name and
			io.left=1 and io.invoiced=0""", (patient.name))
			if inpatient_services:
				for inpatient_service in inpatient_services:
					inpatient_occupancy = frappe.get_doc("Inpatient Occupancy", inpatient_service[0])
					service_unit_type = frappe.get_doc("Healthcare Service Unit Type", frappe.db.get_value("Healthcare Service Unit", inpatient_occupancy.service_unit, "service_unit_type"))
					if service_unit_type and service_unit_type.is_billable == 1:
						hours_occupied = time_diff_in_hours(inpatient_occupancy.check_out, inpatient_occupancy.check_in)
						qty = 0.5
						if hours_occupied > 0:
							actual_qty = hours_occupied / service_unit_type.no_of_hours
							floor = math.floor(actual_qty)
							decimal_part = actual_qty - floor
							if decimal_part > 0.5:
								qty = rounded(floor + 1, 1)
							elif decimal_part < 0.5 and decimal_part > 0:
								qty = rounded(floor + 0.5, 1)
							if qty <= 0:
								qty = 0.5
						item_to_invoice.append({'reference_type': 'Inpatient Occupancy', 'reference_name': inpatient_occupancy.name,
						'service': service_unit_type.item, 'qty': qty})

			return item_to_invoice
		else:
			frappe.throw(_("The Patient {0} do not have customer refrence to invoice").format(patient.name))

def service_item_and_practitioner_charge(doc):
	is_ip = doc_is_ip(doc)
	if is_ip:
		service_item = get_practitioner_service_item(doc.practitioner, "inpatient_visit_charge_item")
		if not service_item:
			service_item = get_healthcare_service_item("inpatient_visit_charge_item")
	else:
		service_item = get_practitioner_service_item(doc.practitioner, "op_consulting_charge_item")
		if not service_item:
			service_item = get_healthcare_service_item("op_consulting_charge_item")
	if not service_item:
		throw_config_service_item(is_ip)

	practitioner_charge = get_practitioner_charge(doc.practitioner, is_ip)
	if not practitioner_charge:
		throw_config_practitioner_charge(is_ip, doc.practitioner)

	return service_item, practitioner_charge

def throw_config_service_item(is_ip):
	service_item_lable = "Out Patient Consulting Charge Item"
	if is_ip:
		service_item_lable = "Inpatient Visit Charge Item"

	msg = _(("Please Configure {0} in ").format(service_item_lable) \
		+ """<b><a href="#Form/Healthcare Settings">Healthcare Settings</a></b>""")
	frappe.throw(msg)

def throw_config_practitioner_charge(is_ip, practitioner):
	charge_name = "OP Consulting Charge"
	if is_ip:
		charge_name = "Inpatient Visit Charge"

	msg = _(("Please Configure {0} for Healthcare Practitioner").format(charge_name) \
		+ """ <b><a href="#Form/Healthcare Practitioner/{0}">{0}</a></b>""".format(practitioner))
	frappe.throw(msg)

def get_practitioner_service_item(practitioner, service_item_field):
	return frappe.db.get_value("Healthcare Practitioner", practitioner, service_item_field)

def get_healthcare_service_item(service_item_field):
	return frappe.db.get_value("Healthcare Settings", None, service_item_field)

def doc_is_ip(doc):
	is_ip = False
	if doc.inpatient_record:
		is_ip = True
	return is_ip

def get_practitioner_charge(practitioner, is_ip):
	if is_ip:
		practitioner_charge = frappe.db.get_value("Healthcare Practitioner", practitioner, "inpatient_visit_charge")
	else:
		practitioner_charge = frappe.db.get_value("Healthcare Practitioner", practitioner, "op_consulting_charge")
	if practitioner_charge:
		return practitioner_charge
	return False

def manage_invoice_submit_cancel(doc, method):
	if doc.items:
		for item in doc.items:
			if item.reference_dt and item.reference_dn:
				if frappe.get_meta(item.reference_dt).has_field("invoiced"):
					set_invoiced(item, method, doc.name)

	if method=="on_submit" and frappe.db.get_value("Healthcare Settings", None, "create_test_on_si_submit") == '1':
		create_multiple("Sales Invoice", doc.name)

def set_invoiced(item, method, ref_invoice=None):
	invoiced = False
	if(method=="on_submit"):
		validate_invoiced_on_submit(item)
		invoiced = True

	if item.reference_dt == 'Clinical Procedure':
		if get_healthcare_service_item('clinical_procedure_consumable_item') == item.item_code:
			frappe.db.set_value(item.reference_dt, item.reference_dn, "consumption_invoiced", invoiced)
		else:
			frappe.db.set_value(item.reference_dt, item.reference_dn, "invoiced", invoiced)
	else:
		frappe.db.set_value(item.reference_dt, item.reference_dn, "invoiced", invoiced)

	if item.reference_dt == 'Patient Appointment':
		if frappe.db.get_value('Patient Appointment', item.reference_dn, 'procedure_template'):
			dt_from_appointment = "Clinical Procedure"
		else:
			manage_fee_validity(item.reference_dn, method, ref_invoice)
			dt_from_appointment = "Patient Encounter"
		manage_doc_for_appoitnment(dt_from_appointment, item.reference_dn, invoiced)

	elif item.reference_dt == 'Lab Prescription':
		manage_prescriptions(invoiced, item.reference_dt, item.reference_dn, "Lab Test", "test_created")

	elif item.reference_dt == 'Procedure Prescription':
		manage_prescriptions(invoiced, item.reference_dt, item.reference_dn, "Clinical Procedure", "procedure_created")

def validate_invoiced_on_submit(item):
	if item.reference_dt == 'Clinical Procedure' and get_healthcare_service_item('clinical_procedure_consumable_item') == item.item_code:
			is_invoiced = frappe.db.get_value(item.reference_dt, item.reference_dn, "consumption_invoiced")
	else:
		is_invoiced = frappe.db.get_value(item.reference_dt, item.reference_dn, "invoiced")
	if is_invoiced == 1:
		frappe.throw(_("The item referenced by {0} - {1} is already invoiced"\
		).format(item.reference_dt, item.reference_dn))

def manage_prescriptions(invoiced, ref_dt, ref_dn, dt, created_check_field):
	created = frappe.db.get_value(ref_dt, ref_dn, created_check_field)
	if created == 1:
		# Fetch the doc created for the prescription
		doc_created = frappe.db.get_value(dt, {'prescription': ref_dn})
		frappe.db.set_value(dt, doc_created, 'invoiced', invoiced)

def manage_fee_validity(appointment_name, method, ref_invoice=None):
	appointment_doc = frappe.get_doc("Patient Appointment", appointment_name)
	validity_exist = validity_exists(appointment_doc.practitioner, appointment_doc.patient)
	do_not_update = False
	visited = 0
	if validity_exist:
		fee_validity = frappe.get_doc("Fee Validity", validity_exist[0][0])
		# Check if the validity is valid
		if (fee_validity.valid_till >= appointment_doc.appointment_date):
			if (method == "on_cancel" and appointment_doc.status != "Closed"):
				visited = fee_validity.visited - 1
				if visited < 0:
					visited = 0
				frappe.db.set_value("Fee Validity", fee_validity.name, "visited", visited)
				do_not_update = True
			elif (fee_validity.visited < fee_validity.max_visit):
				visited = fee_validity.visited + 1
				frappe.db.set_value("Fee Validity", fee_validity.name, "visited", visited)
				do_not_update = True
			else:
				do_not_update = False

		if not do_not_update:
			fee_validity = update_fee_validity(fee_validity, appointment_doc.appointment_date, ref_invoice)
			visited = fee_validity.visited
	else:
		fee_validity = create_fee_validity(appointment_doc.practitioner, appointment_doc.patient, appointment_doc.appointment_date, ref_invoice)
		visited = fee_validity.visited

	# Mark All Patient Appointment invoiced = True in the validity range do not cross the max visit
	if (method == "on_cancel"):
		invoiced = True
	else:
		invoiced = False
	patient_appointments = frappe.get_list("Patient Appointment",{'patient': fee_validity.patient, 'invoiced': invoiced,
	'appointment_date':("<=", fee_validity.valid_till), 'practitioner': fee_validity.practitioner}, order_by="appointment_date")
	if patient_appointments and fee_validity:
		visit = visited
		for appointment in patient_appointments:
			if (method == "on_cancel" and appointment.status != "Closed"):
				visited = visited - 1
				if visited < 0:
					visited = 0
				frappe.db.set_value("Fee Validity", fee_validity.name, "visited", visited)
				frappe.db.set_value("Patient Appointment", appointment.name, "invoiced", False)
				manage_doc_for_appoitnment("Patient Encounter", appointment.name, False)
			elif int(fee_validity.max_visit) > visit:
				visited = visited + 1
				frappe.db.set_value("Fee Validity", fee_validity.name, "visited", visited)
				frappe.db.set_value("Patient Appointment", appointment.name, "invoiced", True)
				manage_doc_for_appoitnment("Patient Encounter", appointment.name, True)
			visit = visit + 1

def manage_doc_for_appoitnment(dt_from_appointment, appointment, invoiced):
	dn_from_appointment = frappe.db.exists(
		dt_from_appointment,
		{
			"appointment": appointment
		}
	)
	if dn_from_appointment:
		frappe.db.set_value(dt_from_appointment, dn_from_appointment, "invoiced", invoiced)

@frappe.whitelist()
def get_drugs_to_invoice(encounter):
	encounter = frappe.get_doc("Patient Encounter", encounter)
	if encounter:
		patient = frappe.get_doc("Patient", encounter.patient)
		if patient and patient.customer:
				item_to_invoice = []
				for drug_line in encounter.drug_prescription:
					if drug_line.drug_code:
						qty = 1
						if frappe.db.get_value("Item", drug_line.drug_code, "stock_uom") == "Nos":
							qty = drug_line.get_quantity()
						item_to_invoice.append({'drug_code': drug_line.drug_code, 'quantity': qty,
						'description': drug_line.dosage+" for "+drug_line.period})
				return item_to_invoice
