#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import requests
import mysql.connector
from pathlib import Path
import sys
from datetime import datetime

# UTF-8 handling
try:
    sys.stdout.reconfigure(encoding='utf-8')
except:
    pass

# === KONFIGURACE ===

# --- Medevio API ---
TOKEN_PATH = Path(__file__).resolve().parent.parent / "token.txt"
GRAPHQL_URL = "https://api.medevio.cz/graphql"

# --- ZPRACOVÁNÍ ---
# Zadejte počet požadavků ke zpracování.
# 0 znamená zpracovat VŠECHNY nesynchronizované požadavky.
PROCESS_LIMIT = 10  # <-- Používáme PROCESS_LIMIT

# --- MySQL DB ---
DB_CONFIG = {
    "host": "192.168.1.76",
    "port": 3307,
    "user": "root",
    "password": "Vlado9674+",
    "database": "medevio",
}


# === Helpers ===

def read_token(p: Path) -> str:
    """Načte Bearer token z textového souboru."""
    t = p.read_text().strip()
    if t.startswith("Bearer "):
        return t.split(" ", 1)[1]
    return t


# === DB Funkce ===

def get_requests_to_process_from_db(limit):
    """
    Získá seznam požadavků (ID, Titul, Jméno, Příjmení) k synchronizaci z MySQL.
    Použije LIMIT, pokud limit > 0.
    """
    if limit == 0:
        print("🔍 Připojuji se k MySQL a hledám **VŠECHNY** nesynchronizované požadavky...")
    else:
        print(f"🔍 Připojuji se k MySQL a hledám **{limit}** nesynchronizovaných požadavků...")

    requests_list = []
    conn = None
    try:
        conn = mysql.connector.connect(**DB_CONFIG)
        cursor = conn.cursor()

        # Základní SQL dotaz
        query = """
        SELECT id, displayTitle, pacient_jmeno, pacient_prijmeni
        FROM pozadavky
        WHERE doneAt IS NULL
        AND noteSyncedAt IS NULL
        ORDER BY updatedAt DESC
        """

        # Podmíněné přidání LIMIT klauzule
        if limit > 0:
            query += f"LIMIT {limit};"
        else:
            query += ";"

        cursor.execute(query)
        results = cursor.fetchall()

        for result in results:
            request_id, display_title, jmeno, prijmeni = result
            requests_list.append({
                "id": request_id,
                "displayTitle": display_title,
                "jmeno": jmeno,
                "prijmeni": prijmeni
            })

        cursor.close()

        if requests_list:
            print(f"✅ Nalezeno {len(requests_list)} požadavků ke zpracování.")
        else:
            print("❌ Nebyl nalezen žádný nesynchronizovaný otevřený požadavek v DB.")

        return requests_list

    except mysql.connector.Error as err:
        print(f"❌ Chyba při připojení/dotazu MySQL: {err}")
        return []
    finally:
        if conn and conn.is_connected():
            conn.close()


def update_db_sync_time(request_id, conn):
    """Aktualizuje sloupec noteSyncedAt v tabulce pozadavky. Používá existující připojení."""
    cursor = conn.cursor()

    current_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')

    update_query = """
    UPDATE pozadavky
    SET noteSyncedAt = %s
    WHERE id = %s;
    """

    cursor.execute(update_query, (current_time, request_id))
    conn.commit()

    cursor.close()
    print(f"   (DB: Čas synchronizace pro {request_id} uložen)")


# === GraphQL Operace (Beze Změny) ===

QUERY_GET_NOTE = r"""
query ClinicRequestNotes_Get($patientRequestId: String!) {
  notes: getClinicPatientRequestNotes(requestId: $patientRequestId) {
    id
    content
  }
}
"""

MUTATION_UPDATE_NOTE = r"""
mutation ClinicRequestNotes_Update($noteInput: UpdateClinicPatientRequestNoteInput!) {
  updateClinicPatientRequestNote(noteInput: $noteInput) {
    id
  }
}
"""

MUTATION_CREATE_NOTE = r"""
mutation ClinicRequestNotes_Create($noteInput: CreateClinicPatientRequestNoteInput!) {
  createClinicPatientRequestNote(noteInput: $noteInput) {
    id
  }
}
"""


def gql(query, variables, token):
    """Obecná funkce pro volání GraphQL endpointu."""
    headers = {
        "Authorization": f"Bearer {token}",
        "Content-Type": "application/json",
        "Accept": "application/json",
    }
    payload = {"query": query, "variables": variables}

    r = requests.post(GRAPHQL_URL, json=payload, headers=headers)
    r.raise_for_status()
    return r.json()


def get_internal_note(request_id, token):
    """Získá jedinou interní poznámku (obsah a ID) pro daný požadavek."""
    data = gql(QUERY_GET_NOTE, {"patientRequestId": request_id}, token)
    notes = data.get("data", {}).get("notes", [])
    return notes[0] if notes else None


def update_internal_note(note_id, new_content, token):
    """Aktualizuje obsah poznámky v Medeviu."""
    variables = {"noteInput": {"id": note_id, "content": new_content}}
    return gql(MUTATION_UPDATE_NOTE, variables, token)


def create_internal_note(request_id, content, token):
    """Vytvoří novou interní poznámku k požadavku v Medeviu."""
    variables = {"noteInput": {"requestId": request_id, "content": content}}
    return gql(MUTATION_CREATE_NOTE, variables, token)


# === MAIN ===

def main():
    token = read_token(TOKEN_PATH)

    # 1. Získat seznam ID požadavků ke zpracování (používáme PROCESS_LIMIT)
    requests_to_process = get_requests_to_process_from_db(PROCESS_LIMIT)

    if not requests_to_process:
        return

    # Pro update DB time otevřeme připojení jednou a použijeme ho v cyklu
    conn = mysql.connector.connect(**DB_CONFIG)

    print("\n=============================================")
    print(f"START ZPRACOVÁNÍ {len(requests_to_process)} POŽADAVKŮ")
    print("=============================================\n")

    for idx, request in enumerate(requests_to_process, 1):
        request_id = request["id"]

        print(
            f"[{idx}/{len(requests_to_process)}] Zpracovávám požadavek: {request['prijmeni']} {request['jmeno']} (ID: {request_id})")

        # 2. Vytvořit text, který chceme přidat/vytvořit
        prepend_text = f"ID: {request_id}\n"

        # 3. Pokusit se získat existující interní poznámku z Medevia
        note = get_internal_note(request_id, token)

        medevio_update_success = False

        if note:
            # A) POZNÁMKA EXISTUJE -> AKTUALIZOVAT
            note_id = note["id"]
            old_content = note["content"] or ""
            new_content = prepend_text + old_content

            try:
                # Odeslání aktualizace
                update_internal_note(note_id, new_content, token)
                print(f"   (Medevio: Poznámka {note_id} **aktualizována**.)")
                medevio_update_success = True
            except requests.exceptions.HTTPError as e:
                print(f"   ❌ Chyba při aktualizaci Medevio API: {e}")

        else:
            # B) POZNÁMKA NEEXISTUJE -> VYTVOŘIT
            new_content = prepend_text.strip()

            try:
                # Odeslání vytvoření
                result = create_internal_note(request_id, new_content, token)
                new_note_id = result.get("data", {}).get("createClinicPatientRequestNote", {}).get("id", "N/A")
                print(f"   (Medevio: Nová poznámka {new_note_id} **vytvořena**.)")
                medevio_update_success = True
            except requests.exceptions.HTTPError as e:
                print(f"   ❌ Chyba při vytváření Medevio API: {e}")

        # 4. AKTUALIZACE ČASOVÉHO RAZÍTKA V DB
        if medevio_update_success:
            update_db_sync_time(request_id, conn)

        print("---------------------------------------------")

    # Uzavřeme připojení k DB po dokončení cyklu
    if conn and conn.is_connected():
        conn.close()
        print("\n✅ Všechny požadavky zpracovány. Připojení k DB uzavřeno.")


if __name__ == "__main__":
    main()