import os
import json
import shutil
import re
from datetime import datetime, timezone

FILES_DIR = "/home/mariserve/discord/filesbot/files/0"
OUTPUT_DIR = "/home/mariserve/discord/filesbot/files"
JSON_FILE = "attachments.json"

DRY_RUN = False

suffix_pattern = re.compile(
    r"^(.*)_([A-Za-z0-9]{6})(\.[^.]*)?$"
)


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


# filename -> list of upload records
file_map = {}

for entry in attachments:
    filename = entry["filename"]

    timestamp = datetime.fromisoformat(
        entry["timestamp"]
    ).replace(tzinfo=timezone.utc)

    file_map.setdefault(filename, []).append({
        "user": entry["owner"]["id"],
        "timestamp": timestamp,
        "username": entry["owner"]["username"]
    })


def move_file(path, user):
    filename = os.path.basename(path)

    dest_dir = os.path.join(
        OUTPUT_DIR,
        user
    )

    dest = os.path.join(
        dest_dir,
        filename
    )

    print(f"[MOVE] {filename} -> {user}")

    if not DRY_RUN:
        os.makedirs(dest_dir, exist_ok=True)

        if not os.path.exists(dest):
            shutil.move(path, dest)
        else:
            print("[NEVERMIND] It already exists")


sorted_count = 0
failed = 0


for filename in os.listdir(FILES_DIR):
    path = os.path.join(FILES_DIR, filename)

    if not os.path.isfile(path):
        continue

    owner = None


    # Method 1: exact filename, first occurrence
    if filename in file_map:
        owner = file_map[filename][0]["user"]


    # Method 2: Discord renamed file matching
    else:
        match = suffix_pattern.match(filename)

        if match:
            base = match.group(1)
            ext = match.group(3) or ""

            original = base + ext

            if original in file_map:
                mtime = datetime.fromtimestamp(
                    os.path.getmtime(path),
                    timezone.utc
                )

                closest = None
                closest_delta = 999999

                for record in file_map[original]:
                    delta = abs(
                        (mtime - record["timestamp"]).total_seconds()
                    )

                    if delta < closest_delta:
                        closest_delta = delta
                        closest = record


                if closest and closest_delta <= 600:
                    owner = closest["user"]
                    print(
                        f"[DATE MATCH] {filename} -> {original} "
                        f"({closest_delta:.1f}s)"
                    )


    if owner:
        move_file(path, owner)
        sorted_count += 1
    else:
        print(f"[FAILED] {filename}")
        failed += 1


print()
print("Finished")
print(f"Sorted: {sorted_count}")
print(f"Remaining: {failed}")

if DRY_RUN:
    print("DRY_RUN enabled")