# -*- coding: utf-8 -*-
"""REDCap_FHIR_Export.ipynb

Automatically generated by Colab.

Original file is located at
    https://colab.research.google.com/drive/1TGPCwYiB4Rv9bWW9yUGPiXZo74Cn_uyc
"""

#@title Instalar dependências e fazer upload dos arquivos
import json
from datetime import datetime
from google.colab import files

#Ler os ficheiros carregados
metadata_file = "/content/metadata.json"
data_file = "/content/data.json"

#Ler arquivos JSON
with open(metadata_file, "r", encoding="utf-8") as f:
    metadata = json.load(f)

with open(data_file, "r", encoding="utf-8") as f:
    records = json.load(f)

#@title Gerar Recursos FHIR
#Construir mapa {field_name: @fhir:path}
fhir_map = {}
for field in metadata:
    annotation = field.get("field_annotation", "")
    if annotation:
        for token in annotation.replace("\n", " ").split():
            token = token.strip()
            if token.startswith("@fhir:"):
                fhir_map[field["field_name"]] = token.replace("@fhir:", "").strip()

print("Total de campos mapeados com @fhir:", len(fhir_map))

#Funções auxiliares para construir estrutura FHIR
def set_fhir_path(obj, path, value):
    keys = path.replace(']', '').split('.')
    obj["resourceType"] = keys[0]
    keys = keys[1:]
    current = obj
    for i, key in enumerate(keys):
        if '[' in key:
            key, idx = key.split('[')
            idx = int(idx)
            current = current.setdefault(key, [])
            while len(current) <= idx:
                current.append({})
            if i == len(keys) - 1:
                current[idx] = value
            else:
                current = current[idx]
        else:
            if i == len(keys) - 1:
                current[key] = value
            else:
                current = current.setdefault(key, {})

def generate_resource(record):
    resource = {}
    for field, path in fhir_map.items():
        value = record.get(field)
        if value and isinstance(value, str):
            value = value.strip()
        if not value:
            continue
        if "date" in path or "time" in path:
            try:
                if len(value) == 10:
                    value = datetime.strptime(value, "%Y-%m-%d").isoformat()
                elif len(value) == 5:
                    value = f"T{value}:00"
                elif len(value) > 10:
                    value = datetime.strptime(value, "%Y-%m-%d %H:%M").isoformat()
            except:
                pass
        if "reference" in path and not value.startswith("Patient/"):
            value = f"Patient/{value}"
        set_fhir_path(resource, path, value)

    # Adicionar status
    status_raw = record.get("plano_terapeutico_oral_complete", "").strip()
    status_map = {
        "Unverified": "intended",
        "Incomplete": "stopped",
        "Complete": "active"
    }
    resource["status"] = status_map.get(status_raw, "unknown")

    # Adicionar subject
    if "subject" not in resource:
      participant_id = (
          record.get("participant_code_estudo") or
          record.get("participant_code")
      )
      if participant_id:
          resource["subject"] = {"reference": f"Patient/{participant_id}"}

    return resource

#Gerar recursos FHIR
resources = [generate_resource(r) for r in records if r.get("medication_name_other")]

#Salvar e baixar arquivo JSON FHIR
output_file = "fhir_medication_statements.json"
with open(output_file, "w", encoding="utf-8") as f:
    json.dump(resources, f, indent=2, ensure_ascii=False)

files.download(output_file)