#!/usr/bin/env python3
import argparse
import base64
import io
import json
import os
import re
import subprocess
import requests
import mysql.connector
import tempfile
from PIL import Image
from urllib.parse import urlparse


def run(cmd, cwd):
    p = subprocess.run(cmd, cwd=cwd, text=True, capture_output=True)
    if p.returncode != 0:
        raise RuntimeError(f"Command failed: {' '.join(cmd)}\n{p.stdout}\n{p.stderr}")
    return p.stdout.strip()


def safe_filename(url: str, fallback: str):
    path = urlparse(url).path
    name = os.path.basename(path) or fallback
    name = re.sub(r"[^a-zA-Z0-9._-]+", "_", name)
    if "." not in name:
        name += ".jpg"
    return name


def parse_images(image_field):
    if not image_field:
        return []
    # Split by comma, but handle URLs that may contain commas (unlikely here)
    return [u.strip() for u in image_field.split(",") if u.strip()]


def resize_image(image_path: str, max_size: int = 512) -> bytes:
    """
    Изменяет размер изображения до max_size пикселей по большей стороне
    и возвращает байты изображения в JPEG формате.
    """
    try:
        with Image.open(image_path) as img:
            print(f"Opening image: {img.format}, {img.size}, {img.mode}")
            
            # Конвертируем в RGB если нужно
            if img.mode != 'RGB':
                img = img.convert('RGB')
                print("Converted to RGB")
            
            # Изменяем размер сохраняя пропорции
            original_size = img.size
            img.thumbnail((max_size, max_size), Image.Resampling.LANCZOS)
            print(f"Resized from {original_size} to {img.size}")
            
            # Сохраняем в байты
            img_bytes = io.BytesIO()
            img.save(img_bytes, format='JPEG', quality=85)
            return img_bytes.getvalue()
    except Exception as e:
        print(f"Error in resize_image: {e}")
        # Возвращаем оригинал если не удалось изменить размер
        with open(image_path, "rb") as f:
            return f.read()


def remove_background(image_path: str, api_key: str) -> bytes:
    """
    Удаляет фон с изображения используя OpenRouter API с Gemini Nano Banana.
    Возвращает обработанное изображение в виде байт.
    """
    try:
        print(f"Processing image: {image_path}")
        print(f"Image exists: {os.path.exists(image_path)}")
        
        # Изменяем размер изображения для API
        try:
            image_data = resize_image(image_path, max_size=1024)
            print(f"Successfully resized image to {len(image_data)} bytes")
        except Exception as e:
            print(f"Resize failed: {e}, using original")
            with open(image_path, "rb") as f:
                image_data = f.read()
        
        base64_image = base64.b64encode(image_data).decode('utf-8')
        print(f"Base64 length: {len(base64_image)}")
        
        # API запрос к OpenRouter с правильным форматом для генерации изображений
        headers = {
            "Authorization": f"Bearer {api_key}",
            "Content-Type": "application/json"
        }
        
        payload = {
            "model": "google/gemini-3.1-flash-image-preview",
            "messages": [
                {
                    "role": "user",
                    "content": [
                        {
                            "type": "text",
                            "text": "Please remove the background from this product image and place it on a pure white background. Return the result as an image."
                        },
                        {
                            "type": "image_url",
                            "image_url": {
                                "url": f"data:image/jpeg;base64,{base64_image}"
                            }
                        }
                    ]
                }
            ],
            "modalities": ["image", "text"],
            "image_config": {
                "aspect_ratio": "1:1",
                "image_size": "1K"
            }
        }
        
        response = requests.post(
            "https://openrouter.ai/api/v1/chat/completions",
            headers=headers,
            json=payload,
            timeout=120
        )
        
        if response.status_code != 200:
            raise RuntimeError(f"OpenRouter API error: {response.status_code} - {response.text}")
        
        result = response.json()
        
        if "choices" not in result or not result["choices"]:
            raise RuntimeError("Invalid response from OpenRouter API")
        
        message = result["choices"][0]["message"]
        
        # Проверяем изображения в ответе
        if "images" in message and message["images"]:
            for image in message["images"]:
                if "image_url" in image and "url" in image["image_url"]:
                    image_url = image["image_url"]["url"]
                    print(f"Found generated image: {image_url[:50]}...")
                    
                    # Извлекаем base64 из data URL
                    if image_url.startswith("data:image/"):
                        base64_data = image_url.split(",", 1)[1]
                        processed_image = base64.b64decode(base64_data)
                        print(f"Successfully decoded image, size: {len(processed_image)} bytes")
                        
                        # Проверяем размер изображения
                        if len(processed_image) < 5000:
                            print("Image too small")
                            raise RuntimeError("Processed image too small")
                        
                        return processed_image
        
        # Если есть текст, выводим его для отладки
        if "content" in message and message["content"]:
            print(f"Text response: {message['content'][:200]}...")
        
        raise RuntimeError("No image found in response")
        
    except Exception as e:
        print(f"Background removal failed: {e}")
        # Возвращаем оригинальное изображение если обработка не удалась
        with open(image_path, "rb") as f:
            return f.read()


def download(url: str, out_path: str, session: requests.Session):
    headers = {
        "User-Agent": "Mozilla/5.0 (compatible; WptestImporter/1.0)",
        "Accept": "image/avif,image/webp,image/apng,image/*,*/*;q=0.8",
        "Referer": url,
    }
    with session.get(url, headers=headers, stream=True, allow_redirects=True, timeout=60) as r:
        r.raise_for_status()
        with open(out_path, "wb") as f:
            for chunk in r.iter_content(chunk_size=1024 * 256):
                if chunk:
                    f.write(chunk)
                    f.write(chunk)


def iter_source_products(mysql_cfg, table, limit=None):
    cnx = mysql.connector.connect(**mysql_cfg)
    cur = cnx.cursor(dictionary=True)
    q = f"SELECT link, title, price, image, description FROM {table} WHERE linkdone = 0 ORDER BY link"
    if limit:
        q += f" LIMIT {int(limit)}"
    cur.execute(q)
    for row in cur:
        yield row
    cur.close()
    cnx.close()


def update_linkdone(mysql_cfg, table, link_key):
    cnx = mysql.connector.connect(**mysql_cfg)
    cur = cnx.cursor()
    cur.execute(f"UPDATE {table} SET linkdone = 1 WHERE link = %s", (link_key,))
    cnx.commit()
    cur.close()
    cnx.close()


def main():
    ap = argparse.ArgumentParser()
    ap.add_argument("--wp-path", required=True, help="Путь к WP")
    ap.add_argument("--wp-user", default="monkoz", help="WP user для wp-cli")
    ap.add_argument("--tmp-dir", default="tmp-import", help="Временная папка внутри wp-path")
    ap.add_argument("--src-host", default="127.0.0.1")
    ap.add_argument("--src-port", type=int, default=3306)
    ap.add_argument("--src-user", required=True)
    ap.add_argument("--src-password", required=True)
    ap.add_argument("--src-db", required=True)
    ap.add_argument("--src-table", default="kleinvalid")
    ap.add_argument("--limit", type=int)
    ap.add_argument("--openrouter-key", default="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", help="OpenRouter API ключ")
    ap.add_argument("--removebg-key", help="remove.bg API key for background removal")
    ap.add_argument("--process-images", action="store_true", help="Обрабатывать изображения через нейросеть для удаления фона")
    args = ap.parse_args()

    wp_path = os.path.abspath(args.wp_path)
    if not os.path.exists(os.path.join(wp_path, "wp-config.php")):
        raise RuntimeError(f"wp-config.php not found in {wp_path}")

    run(["wp", "--info"], cwd=wp_path)

    tmp_dir = os.path.join(wp_path, args.tmp_dir)
    os.makedirs(tmp_dir, exist_ok=True)

    mysql_cfg = {
        "host": args.src_host,
        "port": args.src_port,
        "user": args.src_user,
        "password": args.src_password,
        "database": args.src_db,
    }

    session = requests.Session()

    for row in iter_source_products(mysql_cfg, args.src_table, limit=args.limit):
        link_key = row["link"]
        title = row["title"]
        price = str(row["price"])
        description = row.get("description") or ""
        image_url = row.get("image")
        images_urls = parse_images(image_url)

        # 1) create product
        product_id = run(
            [
                "wp", "wc", "product", "create",
                f"--user={args.wp_user}",
                f"--name={title}",
                "--type=simple",
                "--status=publish",
                f"--regular_price={price}",
                f"--description={description}",
                "--porcelain",
            ],
            cwd=wp_path,
        )
        if not product_id.isdigit():
            raise RuntimeError(f"Unexpected product_id: {product_id}")

        attachment_ids = []
        # 2) download + process + wp media import
        with tempfile.TemporaryDirectory(prefix="wptest_dl_", dir=tmp_dir) as dl_dir:
            for i, url in enumerate(images_urls, start=1):
                local_file = os.path.join(dl_dir, safe_filename(url, f"img_{i}.jpg"))
                download(url, local_file, session=session)
                
                # Обрабатываем изображение через нейросеть если включено
                if args.process_images:
                    try:
                        print(f"Processing image {i} with AI...")
                        processed_image = remove_background(local_file, args.openrouter_key)
                        # Сохраняем обработанное изображение с правильным расширением
                        processed_filename = local_file.rsplit('.', 1)[0] + '_processed.jpg'
                        with open(processed_filename, "wb") as f:
                            f.write(processed_image)
                        # Используем обработанный файл для импорта
                        local_file = processed_filename
                        print(f"Image {i} processed successfully")
                    except Exception as e:
                        print(f"Failed to process image {i}, using original: {e}")
                        # Продолжаем с оригинальным изображением если обработка не удалась
                
                att_id = run(
                    ["wp", "media", "import", local_file, f"--user={args.wp_user}", "--porcelain"],
                    cwd=wp_path,
                )
                if not att_id.isdigit():
                    raise RuntimeError(f"Unexpected attachment_id: {att_id}")
                attachment_ids.append(int(att_id))

        # 3) set featured + gallery
        if attachment_ids:
            featured_id = attachment_ids[0]
            run(
                ["wp", "post", "meta", "update", product_id, "_thumbnail_id", str(featured_id), f"--user={args.wp_user}"],
                cwd=wp_path,
            )
            images_payload = [{"id": aid, "position": pos} for pos, aid in enumerate(attachment_ids)]
            run(
                [
                    "wp", "wc", "product", "update", product_id,
                    f"--user={args.wp_user}",
                    f"--images={json.dumps(images_payload, ensure_ascii=False)}",
                ],
                cwd=wp_path,
            )

        permalink = run(
            ["wp", "wc", "product", "get", product_id, f"--user={args.wp_user}", "--field=permalink"],
            cwd=wp_path,
        )

        # 4) update linkdone = 1
        update_linkdone(mysql_cfg, args.src_table, link_key)

        print(json.dumps({
            "source_link": link_key,
            "wc_product_id": int(product_id),
            "permalink": permalink,
            "attachment_ids": attachment_ids,
        }, ensure_ascii=False))


if __name__ == "__main__":
    main()