# /home/Autopartes/pos/services/image_scraper.py
"""Bulk image downloader and processor for inventory parts.

Provides two capabilities:
1. Bulk import: Accept a list of {part_number, image_url}, download each image,
   resize/optimize with Pillow, save to /pos/static/images/parts/, and update
   the inventory.image_url in the tenant DB.
2. Auto-image: Generate a placeholder image with the part number text when no
   real image is available.
"""

import io
import os
import logging
import requests
from PIL import Image, ImageDraw, ImageFont

logger = logging.getLogger(__name__)

IMAGES_DIR = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'static', 'images', 'parts')
MAX_SIZE = 800
THUMB_SIZE = 300
QUALITY = 85
DOWNLOAD_TIMEOUT = 15


def _ensure_dir():
    """Ensure the parts image directory exists."""
    os.makedirs(IMAGES_DIR, exist_ok=True)


def _process_and_save(image_data, tenant_id, item_id):
    """Resize image, save full + thumbnail, return the relative URL path."""
    _ensure_dir()

    img = Image.open(io.BytesIO(image_data))
    if img.mode not in ('RGB', 'L'):
        img = img.convert('RGB')

    # Full size
    full = img.copy()
    full.thumbnail((MAX_SIZE, MAX_SIZE), Image.LANCZOS)
    full_path = os.path.join(IMAGES_DIR, f'{tenant_id}_{item_id}.jpg')
    full.save(full_path, format='JPEG', quality=QUALITY)

    # Thumbnail
    thumb = img.copy()
    thumb.thumbnail((THUMB_SIZE, THUMB_SIZE), Image.LANCZOS)
    thumb_path = os.path.join(IMAGES_DIR, f'{tenant_id}_{item_id}_thumb.jpg')
    thumb.save(thumb_path, format='JPEG', quality=QUALITY)

    return f'/pos/static/images/parts/{tenant_id}_{item_id}.jpg'


def download_and_process(url, tenant_id, item_id):
    """Download an image from a URL, process it, and save locally.

    Returns the relative URL path on success, or raises on failure.
    """
    resp = requests.get(url, timeout=DOWNLOAD_TIMEOUT, stream=True)
    resp.raise_for_status()

    # Read up to 10 MB
    data = resp.content
    if len(data) > 10 * 1024 * 1024:
        raise ValueError('Image exceeds 10 MB limit')

    return _process_and_save(data, tenant_id, item_id)


def bulk_import(tenant_conn, tenant_id, items):
    """Process a list of {part_number, image_url} items.

    For each item:
      1. Find the inventory item by part_number
      2. Download the image
      3. Resize and save
      4. Update inventory.image_url

    Returns: {imported: int, errors: [str]}
    """
    imported = 0
    errors = []
    cur = tenant_conn.cursor()

    try:
        for entry in items:
            pn = (entry.get('part_number') or '').strip()
            url = (entry.get('image_url') or '').strip()

            if not pn or not url:
                errors.append(f'Missing part_number or image_url: {entry}')
                continue

            # Find inventory item
            cur.execute(
                "SELECT id FROM inventory WHERE part_number = %s AND is_active = true LIMIT 1",
                (pn,)
            )
            row = cur.fetchone()
            if not row:
                errors.append(f'Part not found: {pn}')
                continue

            item_id = row[0]

            try:
                rel_url = download_and_process(url, tenant_id, item_id)
                cur.execute(
                    "UPDATE inventory SET image_url = %s WHERE id = %s",
                    (rel_url, item_id)
                )
                tenant_conn.commit()
                imported += 1
            except Exception as e:
                tenant_conn.rollback()
                errors.append(f'{pn}: {str(e)}')
                logger.warning('Failed to import image for %s: %s', pn, e)

    finally:
        cur.close()

    return {'imported': imported, 'errors': errors}


def generate_placeholder(tenant_id, item_id, part_number, name=''):
    """Generate a placeholder image with the part number text.

    Creates a 400x400 gray image with the part number centered.
    Returns the relative URL path.
    """
    _ensure_dir()

    width, height = 400, 400
    bg_color = (240, 240, 240)
    text_color = (80, 80, 80)
    accent_color = (245, 166, 35)  # Nexus orange

    img = Image.new('RGB', (width, height), bg_color)
    draw = ImageDraw.Draw(img)

    # Draw accent bar at top
    draw.rectangle([0, 0, width, 6], fill=accent_color)

    # Draw part icon placeholder (box outline)
    box_margin = 100
    draw.rectangle(
        [box_margin, box_margin, width - box_margin, height - box_margin - 40],
        outline=(200, 200, 200), width=2
    )

    # Try to use a built-in font, fall back to default
    try:
        font_large = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf", 24)
        font_small = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", 14)
    except (IOError, OSError):
        font_large = ImageFont.load_default()
        font_small = font_large

    # Part number (centered)
    pn_text = part_number or 'SIN NUMERO'
    bbox = draw.textbbox((0, 0), pn_text, font=font_large)
    tw = bbox[2] - bbox[0]
    draw.text(((width - tw) / 2, height - 80), pn_text, fill=accent_color, font=font_large)

    # Name (centered, below part number)
    if name:
        display_name = name[:30] + ('...' if len(name) > 30 else '')
        bbox2 = draw.textbbox((0, 0), display_name, font=font_small)
        tw2 = bbox2[2] - bbox2[0]
        draw.text(((width - tw2) / 2, height - 50), display_name, fill=text_color, font=font_small)

    # "SIN IMAGEN" text centered in box
    no_img = 'SIN IMAGEN'
    bbox3 = draw.textbbox((0, 0), no_img, font=font_small)
    tw3 = bbox3[2] - bbox3[0]
    draw.text(((width - tw3) / 2, (height - 40) / 2), no_img, fill=(180, 180, 180), font=font_small)

    # Save
    full_path = os.path.join(IMAGES_DIR, f'{tenant_id}_{item_id}.jpg')
    img.save(full_path, format='JPEG', quality=QUALITY)

    thumb = img.copy()
    thumb.thumbnail((THUMB_SIZE, THUMB_SIZE), Image.LANCZOS)
    thumb_path = os.path.join(IMAGES_DIR, f'{tenant_id}_{item_id}_thumb.jpg')
    thumb.save(thumb_path, format='JPEG', quality=QUALITY)

    return f'/pos/static/images/parts/{tenant_id}_{item_id}.jpg'
