"""CRM Blueprint: activities, tags, loyalty, analytics.

Prefixes:
  /pos/api/customers/<id>/activities
  /pos/api/customers/<id>/tags
  /pos/api/customers/<id>/loyalty
  /pos/api/customers/<id>/analytics
  /pos/api/tags
  /pos/api/rewards
"""

from flask import Blueprint, request, jsonify, g
from middleware import require_auth
from tenant_db import get_tenant_conn
from services.crm_engine import (
    log_activity, get_activities,
    create_tag, list_tags, assign_tag, remove_tag, get_customer_tags,
    add_loyalty_points, redeem_points, get_loyalty_history,
    create_reward, list_rewards,
    get_customer_analytics,
)

crm_bp = Blueprint('crm', __name__, url_prefix='/pos/api')


# ─── Customer Activities ─────────────────────────────

@crm_bp.route('/customers/<int:customer_id>/activities', methods=['GET'])
@require_auth('customers.view')
def customer_activities(customer_id):
    activity_type = request.args.get('type')
    limit = min(int(request.args.get('limit', 50)), 200)
    conn = get_tenant_conn(g.tenant_id)
    try:
        activities = get_activities(conn, customer_id, activity_type=activity_type, limit=limit)
        return jsonify({'activities': activities})
    finally:
        conn.close()


@crm_bp.route('/customers/<int:customer_id>/activities', methods=['POST'])
@require_auth('customers.edit')
def add_customer_activity(customer_id):
    data = request.get_json() or {}
    activity_type = data.get('activity_type', 'note')
    conn = get_tenant_conn(g.tenant_id)
    try:
        activity_id = log_activity(
            conn, customer_id, activity_type,
            title=data.get('title'),
            description=data.get('description'),
            metadata=data.get('metadata'),
            employee_id=getattr(g, 'employee_id', None),
        )
        return jsonify({'id': activity_id, 'message': 'Activity logged'}), 201
    finally:
        conn.close()


# ─── Customer Tags ─────────────────────────────

@crm_bp.route('/tags', methods=['GET'])
@require_auth('customers.view')
def get_tags():
    conn = get_tenant_conn(g.tenant_id)
    try:
        tags = list_tags(conn, g.tenant_id)
        return jsonify({'tags': tags})
    finally:
        conn.close()


@crm_bp.route('/tags', methods=['POST'])
@require_auth('customers.edit')
def create_new_tag():
    data = request.get_json() or {}
    if not data.get('name'):
        return jsonify({'error': 'name is required'}), 400
    conn = get_tenant_conn(g.tenant_id)
    try:
        tag_id = create_tag(conn, g.tenant_id, data['name'],
                           color=data.get('color', '#6B7280'),
                           description=data.get('description'))
        return jsonify({'id': tag_id, 'message': 'Tag created'}), 201
    finally:
        conn.close()


@crm_bp.route('/customers/<int:customer_id>/tags', methods=['GET'])
@require_auth('customers.view')
def get_customer_tags_endpoint(customer_id):
    conn = get_tenant_conn(g.tenant_id)
    try:
        tags = get_customer_tags(conn, customer_id)
        return jsonify({'tags': tags})
    finally:
        conn.close()


@crm_bp.route('/customers/<int:customer_id>/tags', methods=['POST'])
@require_auth('customers.edit')
def assign_customer_tag(customer_id):
    data = request.get_json() or {}
    tag_id = data.get('tag_id')
    if not tag_id:
        return jsonify({'error': 'tag_id is required'}), 400
    conn = get_tenant_conn(g.tenant_id)
    try:
        assign_tag(conn, customer_id, tag_id, assigned_by=getattr(g, 'employee_id', None))
        return jsonify({'message': 'Tag assigned'})
    finally:
        conn.close()


@crm_bp.route('/customers/<int:customer_id>/tags/<int:tag_id>', methods=['DELETE'])
@require_auth('customers.edit')
def remove_customer_tag(customer_id, tag_id):
    conn = get_tenant_conn(g.tenant_id)
    try:
        remove_tag(conn, customer_id, tag_id)
        return jsonify({'message': 'Tag removed'})
    finally:
        conn.close()


# ─── Loyalty ─────────────────────────────

@crm_bp.route('/customers/<int:customer_id>/loyalty', methods=['GET'])
@require_auth('customers.view')
def get_loyalty(customer_id):
    conn = get_tenant_conn(g.tenant_id)
    try:
        history = get_loyalty_history(conn, customer_id)
        # Get current balance
        cur = conn.cursor()
        cur.execute("SELECT loyalty_points_balance, loyalty_tier FROM customers WHERE id = %s", (customer_id,))
        row = cur.fetchone()
        cur.close()
        return jsonify({
            'balance': row[0] or 0,
            'tier': row[1] or 'bronze',
            'history': history,
        })
    finally:
        conn.close()


@crm_bp.route('/customers/<int:customer_id>/loyalty/add', methods=['POST'])
@require_auth('customers.edit')
def add_loyalty(customer_id):
    data = request.get_json() or {}
    points = int(data.get('points', 0))
    if points <= 0:
        return jsonify({'error': 'points must be > 0'}), 400
    conn = get_tenant_conn(g.tenant_id)
    try:
        point_id = add_loyalty_points(
            conn, customer_id, points,
            points_type=data.get('points_type', 'earned'),
            source_type=data.get('source_type'),
            source_id=data.get('source_id'),
            description=data.get('description'),
            expires_at=data.get('expires_at'),
        )
        return jsonify({'id': point_id, 'message': f'{points} points added'}), 201
    finally:
        conn.close()


@crm_bp.route('/customers/<int:customer_id>/loyalty/redeem', methods=['POST'])
@require_auth('customers.edit')
def redeem_loyalty(customer_id):
    data = request.get_json() or {}
    points = int(data.get('points', 0))
    if points <= 0:
        return jsonify({'error': 'points must be > 0'}), 400
    conn = get_tenant_conn(g.tenant_id)
    try:
        redemption_id = redeem_points(
            conn, customer_id, points,
            reward_id=data.get('reward_id'),
            reward_value=data.get('reward_value'),
            description=data.get('description'),
            employee_id=getattr(g, 'employee_id', None),
        )
        return jsonify({'id': redemption_id, 'message': f'{points} points redeemed'}), 201
    except ValueError as e:
        return jsonify({'error': str(e)}), 400


# ─── Rewards Catalog ─────────────────────────────

@crm_bp.route('/rewards', methods=['GET'])
@require_auth('customers.view')
def get_rewards():
    conn = get_tenant_conn(g.tenant_id)
    try:
        rewards = list_rewards(conn, g.tenant_id)
        return jsonify({'rewards': rewards})
    finally:
        conn.close()


@crm_bp.route('/rewards', methods=['POST'])
@require_auth('customers.edit')
def create_new_reward():
    data = request.get_json() or {}
    if not data.get('name') or data.get('points_cost') is None:
        return jsonify({'error': 'name and points_cost are required'}), 400
    conn = get_tenant_conn(g.tenant_id)
    try:
        reward_id = create_reward(
            conn, g.tenant_id, data['name'], int(data['points_cost']),
            reward_type=data.get('reward_type', 'discount'),
            reward_value=data.get('reward_value'),
            description=data.get('description'),
        )
        return jsonify({'id': reward_id, 'message': 'Reward created'}), 201
    finally:
        conn.close()


# ─── Customer Analytics ─────────────────────────────

@crm_bp.route('/customers/<int:customer_id>/analytics', methods=['GET'])
@require_auth('customers.view')
def customer_analytics(customer_id):
    conn = get_tenant_conn(g.tenant_id)
    try:
        analytics = get_customer_analytics(conn, customer_id)
        return jsonify(analytics)
    finally:
        conn.close()
