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

"""
Sync open requests: checks each request marked as open in MySQL (doneAt IS NULL
AND removedAt IS NULL) against the Medevio API. If the API shows the request is
closed (doneAt) or removed (removedAt), updates MySQL accordingly.
"""

import json
import sys
import time
import requests
import pymysql
from pathlib import Path
from datetime import datetime

# ==============================
# UTF-8 output (Windows friendly)
# ==============================
try:
    sys.stdout.reconfigure(encoding="utf-8")
    sys.stderr.reconfigure(encoding="utf-8")
except AttributeError:
    import io
    sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8")
    sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding="utf-8")

# ==============================
# DRY RUN - set to True to only print what would be updated, False to actually update
# ==============================
DRY_RUN = False

# ==============================
# CONFIG
# ==============================
GRAPHQL_URL = "https://api.medevio.cz/graphql"
CLINIC_SLUG = "mudr-buzalkova"

TOKEN_PATH = Path(__file__).resolve().parent.parent / "token.txt"

gateway_token = TOKEN_PATH.read_text(encoding="utf-8").strip()
headers = {
    "content-type": "application/json",
    "authorization": f"Bearer {gateway_token}",
    "origin": "https://my.medevio.cz",
    "referer": "https://my.medevio.cz/",
}

DB_CONFIG = {
    "host": "192.168.1.76",
    "port": 3306,
    "user": "root",
    "password": "Vlado9674+",
    "database": "medevio",
    "charset": "utf8mb4",
    "cursorclass": pymysql.cursors.DictCursor,
}

GRAPHQL_QUERY = """
query GetPatientRequest2($requestId: UUID!, $clinicSlug: String!) {
  request: getPatientRequest2(patientRequestId: $requestId, clinicSlug: $clinicSlug) {
    id
    doneAt
    removedAt
    updatedAt
  }
}
"""


def fix_datetime(dt_str):
    if not dt_str:
        return None
    try:
        return datetime.fromisoformat(dt_str.replace("Z", "+00:00"))
    except Exception:
        return None


def fetch_request(request_id):
    payload = {
        "operationName": "GetPatientRequest2",
        "query": GRAPHQL_QUERY,
        "variables": {
            "requestId": request_id,
            "clinicSlug": CLINIC_SLUG,
        },
    }
    for attempt in range(3):
        try:
            r = requests.post(GRAPHQL_URL, json=payload, headers=headers, timeout=30)
            break
        except (requests.ConnectionError, requests.Timeout, requests.exceptions.RequestException) as e:
            print(f"  ⚠️ Attempt {attempt+1}/3 failed: {e}")
            time.sleep(2)
    else:
        print(f"  ❌ Connection failed after 3 attempts for {request_id}")
        return None
    if r.status_code != 200:
        print(f"  ❌ HTTP {r.status_code} for {request_id}")
        return None
    data = r.json()
    if "errors" in data:
        print(f"  ❌ API error for {request_id}: {data['errors']}")
        return None
    return data.get("data", {}).get("request")


# ==============================
# MAIN
# ==============================
conn = pymysql.connect(**DB_CONFIG)

# 1) Read all open requests from MySQL
with conn.cursor() as cur:
    cur.execute(
        "SELECT id, displayTitle, pacient_prijmeni, pacient_jmeno "
        "FROM pozadavky WHERE doneAt IS NULL AND removedAt IS NULL"
    )
    open_requests = cur.fetchall()

mode = "DRY RUN" if DRY_RUN else "LIVE"
print(f"🔧 Mode: {mode}")
print(f"📋 Found {len(open_requests)} open requests in MySQL.\n")

updated = 0
errors = 0

for i, req in enumerate(open_requests, 1):
    rid = req["id"]
    name = f"{req.get('pacient_prijmeni', '')} {req.get('pacient_jmeno', '')}".strip()
    title = req.get("displayTitle", "")
    print(f"[{i}/{len(open_requests)}] {name} – {title} ({rid})")

    api_data = fetch_request(rid)
    if api_data is None:
        errors += 1
        continue

    api_done = api_data.get("doneAt")
    api_removed = api_data.get("removedAt")
    api_updated = api_data.get("updatedAt")

    if api_done or api_removed:
        done_dt = fix_datetime(api_done)
        removed_dt = fix_datetime(api_removed)
        updated_dt = fix_datetime(api_updated)

        status = "DONE" if api_done else "REMOVED"

        if DRY_RUN:
            print(f"  🔍 Would update → {status} (doneAt={api_done}, removedAt={api_removed})")
        else:
            with conn.cursor() as cur:
                cur.execute(
                    "UPDATE pozadavky SET doneAt = %s, removedAt = %s, updatedAt = %s WHERE id = %s",
                    (done_dt, removed_dt, updated_dt, rid),
                )
            conn.commit()
            print(f"  ✅ Updated → {status}")

        updated += 1
    else:
        print(f"  ⏳ Still open")

    # Be gentle with the API
    time.sleep(1)

conn.close()

print(f"\n{'='*50}")
print(f"📊 Total open in MySQL: {len(open_requests)}")
print(f"✅ Updated (closed/removed): {updated}")
print(f"⏳ Still open: {len(open_requests) - updated - errors}")
print(f"❌ Errors: {errors}")
