# /home/Autopartes/pos/services/plate_lookup.py
"""Mexican license plate lookup service.

Validates Mexican plate formats and searches the local plate_vehicles table.
Since there is no free REPUVE API, this uses a tenant-local lookup table
populated when customers register their vehicles.

Mexican plate formats:
  - Standard:  ABC-1234  (3 letters + hyphen + 3-4 digits)
  - Alternate: AB-123-C  (2 letters + 3 digits + 1 letter)
  - Also accepted without hyphens: ABC1234, AB123C
"""

import re

# Patterns for Mexican plates (with or without hyphens)
_PATTERNS = [
    re.compile(r'^[A-Z]{3}-?\d{3,4}$'),       # ABC-1234 or ABC1234
    re.compile(r'^[A-Z]{2}-?\d{3}-?[A-Z]$'),   # AB-123-C or AB123C
]


def normalize_plate(plate):
    """Normalize a plate string: uppercase, strip spaces/hyphens."""
    if not plate:
        return ''
    return re.sub(r'[\s\-]+', '', plate.strip().upper())


def is_valid_mexican_plate(plate):
    """Check if a string looks like a valid Mexican license plate."""
    norm = normalize_plate(plate)
    return any(p.match(norm) for p in _PATTERNS)


def search_plate(tenant_conn, plate):
    """Search plate_vehicles table for a matching plate.

    Returns dict with vehicle info or None if not found.
    """
    norm = normalize_plate(plate)
    if not norm:
        return None

    cur = tenant_conn.cursor()
    try:
        cur.execute("""
            SELECT id, plate, make, model, year, vin, customer_id, created_at
            FROM plate_vehicles
            WHERE REPLACE(REPLACE(UPPER(plate), '-', ''), ' ', '') = %s
            LIMIT 1
        """, (norm,))
        row = cur.fetchone()
        if not row:
            return None
        return {
            'id': row[0],
            'plate': row[1],
            'make': row[2],
            'model': row[3],
            'year': row[4],
            'vin': row[5],
            'customer_id': row[6],
            'created_at': row[7].isoformat() if row[7] else None,
        }
    finally:
        cur.close()


def register_plate(tenant_conn, plate, make=None, model=None, year=None,
                    vin=None, customer_id=None):
    """Register or update a plate-to-vehicle mapping.

    Returns the plate_vehicles record id.
    """
    norm_display = normalize_plate(plate)
    if not norm_display:
        raise ValueError('Plate is required')

    # Format nicely: ABC-1234 or AB-123-C
    if re.match(r'^[A-Z]{3}\d{3,4}$', norm_display):
        display = norm_display[:3] + '-' + norm_display[3:]
    elif re.match(r'^[A-Z]{2}\d{3}[A-Z]$', norm_display):
        display = norm_display[:2] + '-' + norm_display[2:5] + '-' + norm_display[5:]
    else:
        display = norm_display

    cur = tenant_conn.cursor()
    try:
        cur.execute("""
            INSERT INTO plate_vehicles (plate, make, model, year, vin, customer_id)
            VALUES (%s, %s, %s, %s, %s, %s)
            ON CONFLICT (plate) DO UPDATE SET
                make = COALESCE(EXCLUDED.make, plate_vehicles.make),
                model = COALESCE(EXCLUDED.model, plate_vehicles.model),
                year = COALESCE(EXCLUDED.year, plate_vehicles.year),
                vin = COALESCE(EXCLUDED.vin, plate_vehicles.vin),
                customer_id = COALESCE(EXCLUDED.customer_id, plate_vehicles.customer_id)
            RETURNING id
        """, (display, make, model, year, vin, customer_id))
        rec_id = cur.fetchone()[0]
        tenant_conn.commit()
        return rec_id
    except Exception:
        tenant_conn.rollback()
        raise
    finally:
        cur.close()
