"""Models (equipment models) API endpoints - Full CRUD."""

from flask import Blueprint, request
from flask_jwt_extended import jwt_required

from shopdb.extensions import db
from shopdb.core.models import Model
from shopdb.utils.responses import (
    success_response,
    error_response,
    paginated_response,
    ErrorCodes
)
from shopdb.utils.pagination import get_pagination_params, paginate_query

models_bp = Blueprint('models', __name__)


@models_bp.route('', methods=['GET'])
@jwt_required(optional=True)
def list_models():
    """List all equipment models."""
    page, per_page = get_pagination_params(request)

    query = Model.query

    if request.args.get('active', 'true').lower() != 'false':
        query = query.filter(Model.isactive == True)

    if vendor_id := request.args.get('vendor', type=int):
        query = query.filter(Model.vendorid == vendor_id)

    if machinetype_id := request.args.get('machinetype', type=int):
        query = query.filter(Model.machinetypeid == machinetype_id)

    if search := request.args.get('search'):
        query = query.filter(Model.modelnumber.ilike(f'%{search}%'))

    query = query.order_by(Model.modelnumber)

    items, total = paginate_query(query, page, per_page)

    data = []
    for m in items:
        d = m.to_dict()
        d['vendor'] = m.vendor.vendor if m.vendor else None
        d['machinetype'] = m.machinetype.machinetype if m.machinetype else None
        data.append(d)

    return paginated_response(data, page, per_page, total)


@models_bp.route('/<int:model_id>', methods=['GET'])
@jwt_required(optional=True)
def get_model(model_id: int):
    """Get a single model."""
    m = Model.query.get(model_id)

    if not m:
        return error_response(
            ErrorCodes.NOT_FOUND,
            f'Model with ID {model_id} not found',
            http_code=404
        )

    data = m.to_dict()
    data['vendor'] = m.vendor.to_dict() if m.vendor else None
    data['machinetype'] = m.machinetype.to_dict() if m.machinetype else None

    return success_response(data)


@models_bp.route('', methods=['POST'])
@jwt_required()
def create_model():
    """Create a new model."""
    data = request.get_json()

    if not data or not data.get('modelnumber'):
        return error_response(ErrorCodes.VALIDATION_ERROR, 'modelnumber is required')

    # Check duplicate
    existing = Model.query.filter_by(
        modelnumber=data['modelnumber'],
        vendorid=data.get('vendorid')
    ).first()
    if existing:
        return error_response(
            ErrorCodes.CONFLICT,
            f"Model '{data['modelnumber']}' already exists for this vendor",
            http_code=409
        )

    m = Model(
        modelnumber=data['modelnumber'],
        vendorid=data.get('vendorid'),
        machinetypeid=data.get('machinetypeid'),
        description=data.get('description'),
        imageurl=data.get('imageurl'),
        documentationurl=data.get('documentationurl'),
        notes=data.get('notes')
    )

    db.session.add(m)
    db.session.commit()

    return success_response(m.to_dict(), message='Model created', http_code=201)


@models_bp.route('/<int:model_id>', methods=['PUT'])
@jwt_required()
def update_model(model_id: int):
    """Update a model."""
    m = Model.query.get(model_id)

    if not m:
        return error_response(
            ErrorCodes.NOT_FOUND,
            f'Model with ID {model_id} not found',
            http_code=404
        )

    data = request.get_json()
    if not data:
        return error_response(ErrorCodes.VALIDATION_ERROR, 'No data provided')

    for key in ['modelnumber', 'vendorid', 'machinetypeid', 'description', 'imageurl', 'documentationurl', 'notes', 'isactive']:
        if key in data:
            setattr(m, key, data[key])

    db.session.commit()
    return success_response(m.to_dict(), message='Model updated')


@models_bp.route('/<int:model_id>', methods=['DELETE'])
@jwt_required()
def delete_model(model_id: int):
    """Delete (deactivate) a model."""
    m = Model.query.get(model_id)

    if not m:
        return error_response(
            ErrorCodes.NOT_FOUND,
            f'Model with ID {model_id} not found',
            http_code=404
        )

    m.isactive = False
    db.session.commit()

    return success_response(message='Model deleted')
