#!/usr/bin/env python3
# ВОЗВРАТ: переносим файлы из «Фото домов» обратно в исходные папки + удаляем «Фото домов»
import json, os, time, urllib.request, urllib.parse
from concurrent.futures import ThreadPoolExecutor, as_completed

tok = None
for line in open("/root/site/yandex/.env_hram", encoding="utf-8"):
    if line.startswith("YANDEX2_ACCESS_TOKEN="):
        tok = line.split("=", 1)[1].strip()
H = {"Authorization": f"OAuth {tok}"}

def api_move(src, dst, overwrite=False):
    url = "https://cloud-api.yandex.net/v1/disk/resources/move?" + urllib.parse.urlencode({
        "from": src, "path": dst, "overwrite": "true" if overwrite else "false"})
    req = urllib.request.Request(url, method="POST", headers=H)
    try:
        with urllib.request.urlopen(req, timeout=120) as r:
            return r.status
    except urllib.error.HTTPError as e:
        body = e.read().decode(errors="replace")
        return e.code if "already exists" in body or "ConflictError" in body or e.code == 409 else e.code

def exists(path):
    url = "https://cloud-api.yandex.net/v1/disk/resources?path=" + urllib.parse.quote(path)
    req = urllib.request.Request(url, headers=H)
    try:
        with urllib.request.urlopen(req, timeout=60) as r:
            return True
    except urllib.error.HTTPError:
        return False

def disk_delete(path):
    url = "https://cloud-api.yandex.net/v1/disk/resources?path=" + urllib.parse.quote(path)
    req = urllib.request.Request(url, method="DELETE", headers=H)
    try:
        with urllib.request.urlopen(req, timeout=120) as r:
            return r.status
    except urllib.error.HTTPError as e:
        return e.code

# Воспроизводим ТОЧНО те же dst-имена, что назначал move_all_photos.py
idx = json.load(open("/root/site/video/hram_photos_index.json"))
photos = []
for folder, items in idx.items():
    for p in items:
        photos.append({"src": p[0], "name": p[1]})

gps_cache = json.load(open("/root/site/video/gps_cache2.json", encoding="utf-8"))
clusters = json.load(open("/root/site/video/clusters_geocoded.json", encoding="utf-8"))
KEEP_DIRS = {1, 3, 5, 6, 12}
cluster_keys = set()
for cl in clusters:
    if cl["cluster"] in KEEP_DIRS:
        for k in cl["keys"]:
            cluster_keys.add(k)
pending = [p for p in photos if p["src"] not in cluster_keys]

used = {p["name"] for p in photos if p["src"] in cluster_keys}
planned = {}
def unique_name(name):
    if name not in used and name not in planned:
        planned[name] = True
        return name
    base, ext = os.path.splitext(name)
    i = 2
    while True:
        cand = f"{base} ({i}){ext}"
        if cand not in used and cand not in planned:
            planned[cand] = True
            return cand
        i += 1

jobs = []
for p in pending:
    dst = "/Фото домов/" + unique_name(p["name"])
    jobs.append({"src": p["src"], "orig": p["name"], "dst": dst})

print(f"Всего задач на возврат: {len(jobs)}")

def work(job):
    # если dst существует — это перемещённый файл, возвращаем в src
    if not exists(job["dst"]):
        return (job["src"], True, "не был перемещён")
    # если в src уже есть файл (конфликт при возврате) — перезаписываем (мы вернули оригинал)
    st = api_move(job["dst"], job["src"], overwrite=True)
    if st in (200, 201, 202):
        return (job["src"], True, st)
    return (job["src"], False, f"HTTP {st}")

t0 = time.time()
ok = skipped = fail = 0
with ThreadPoolExecutor(max_workers=5) as ex:
    futs = [ex.submit(work, j) for j in jobs]
    for i, fut in enumerate(as_completed(futs), 1):
        src, success, info = fut.result()
        if success and info == "не был перемещён":
            skipped += 1
        elif success:
            ok += 1
        else:
            fail += 1
        if i % 150 == 0:
            print(f"  {i}/{len(jobs)} | возвращено: {ok} | пропущено: {skipped} | ошибок: {fail} | {time.time()-t0:.0f}с")

print(f"\nВозврат файлов: OK {ok}, пропущено (не перемещались) {skipped}, ошибок {fail}")

# Проверка: все ли src существуют
missing = [j["src"] for j in jobs if not exists(j["src"])]
print("Отсутствующих исходников после возврата:", len(missing))
for m in missing[:10]:
    print("  MISS:", m)

# Удаляем «Фото домов» (копии «По объектам» + возможные остатки)
if exists("/Фото домов"):
    st = disk_delete("/Фото домов")
    print("Удаление «Фото домов»:", st)
else:
    print("«Фото домов» уже нет")
