"""Support Teams API endpoints - teams and their nested contacts."""

from flask import Blueprint, request
from flask_jwt_extended import jwt_required

from shopdb.extensions import db
from shopdb.core.models import (
    SupportTeam, SupportTeamContact, Application, AuditLog
)
from shopdb.utils.responses import (
    success_response,
    error_response,
    ErrorCodes
)
from shopdb.utils.authz import require_role
from shopdb.utils.import_mode import apply_import_timestamps

supportteams_bp = Blueprint('supportteams', __name__)


@supportteams_bp.route('', methods=['GET'])
@jwt_required(optional=True)
def list_support_teams():
    """List support teams (with contacts). ?active and ?teamname filters."""
    query = SupportTeam.query

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

    # Exact-match natural-key lookup for idempotent import (team name).
    if exactteamname := request.args.get('teamname'):
        query = query.filter(SupportTeam.teamname == exactteamname)

    teams = query.order_by(SupportTeam.teamname).all()
    return success_response([team.to_dict() for team in teams])


@supportteams_bp.route('/<int:team_id>', methods=['GET'])
@jwt_required(optional=True)
def get_support_team(team_id: int):
    """Get a single support team with its contacts."""
    team = db.session.get(SupportTeam, team_id)
    if not team:
        return error_response(ErrorCodes.NOT_FOUND, 'Support team not found',
                              http_code=404)
    return success_response(team.to_dict())


@supportteams_bp.route('', methods=['POST'])
@jwt_required()
@require_role('admin')
def create_support_team():
    """Create a new support team."""
    data = request.get_json()
    if not data or not data.get('teamname'):
        return error_response(ErrorCodes.VALIDATION_ERROR, 'teamname is required')

    if SupportTeam.query.filter_by(teamname=data['teamname']).first():
        return error_response(
            ErrorCodes.CONFLICT,
            f"Support team '{data['teamname']}' already exists",
            http_code=409)

    team = SupportTeam(
        teamname=data['teamname'],
        teamurl=data.get('teamurl'),
        webhookurl=data.get('webhookurl'),
        isactive=data.get('isactive', True))

    db.session.add(team)
    apply_import_timestamps(team, data)
    db.session.flush()

    AuditLog.log('created', 'SupportTeam', entityid=team.supportteamid,
                 entityname=team.teamname)
    db.session.commit()

    return success_response(team.to_dict(), message='Support team created',
                            http_code=201)


@supportteams_bp.route('/<int:team_id>', methods=['PUT'])
@jwt_required()
@require_role('admin')
def update_support_team(team_id: int):
    """Update a support team."""
    team = db.session.get(SupportTeam, team_id)
    if not team:
        return error_response(ErrorCodes.NOT_FOUND, 'Support team not found',
                              http_code=404)

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

    if 'teamname' in data and data['teamname'] != team.teamname:
        if SupportTeam.query.filter_by(teamname=data['teamname']).first():
            return error_response(
                ErrorCodes.CONFLICT,
                f"Support team '{data['teamname']}' already exists",
                http_code=409)

    for key in ['teamname', 'teamurl', 'webhookurl', 'isactive']:
        if key in data:
            setattr(team, key, data[key])

    apply_import_timestamps(team, data)
    AuditLog.log('updated', 'SupportTeam', entityid=team.supportteamid,
                 entityname=team.teamname)
    db.session.commit()

    return success_response(team.to_dict(), message='Support team updated')


@supportteams_bp.route('/<int:team_id>', methods=['DELETE'])
@jwt_required()
@require_role('admin')
def delete_support_team(team_id: int):
    """Delete a support team; 409 while any application references it."""
    team = db.session.get(SupportTeam, team_id)
    if not team:
        return error_response(ErrorCodes.NOT_FOUND, 'Support team not found',
                              http_code=404)

    refcount = Application.query.filter_by(supportteamid=team_id).count()
    if refcount:
        return error_response(
            ErrorCodes.CONFLICT,
            f'{refcount} application(s) still reference this support team',
            http_code=409)

    AuditLog.log('deleted', 'SupportTeam', entityid=team.supportteamid,
                 entityname=team.teamname)
    db.session.delete(team)  # cascade removes its contacts
    db.session.commit()

    return success_response(message='Support team deleted')


# ---- Contacts (nested under a team) ----

@supportteams_bp.route('/<int:team_id>/contacts', methods=['POST'])
@jwt_required()
@require_role('admin')
def create_contact(team_id: int):
    """Add a contact to a support team."""
    team = db.session.get(SupportTeam, team_id)
    if not team:
        return error_response(ErrorCodes.NOT_FOUND, 'Support team not found',
                              http_code=404)

    data = request.get_json()
    if not data or not data.get('name'):
        return error_response(ErrorCodes.VALIDATION_ERROR, 'name is required')

    contact = SupportTeamContact(
        supportteamid=team_id,
        name=data['name'],
        sso=data.get('sso'),
        sortorder=data.get('sortorder', 0),
        isactive=data.get('isactive', True))

    db.session.add(contact)
    apply_import_timestamps(contact, data)
    db.session.flush()

    AuditLog.log('created', 'SupportTeamContact', entityid=contact.contactid,
                 entityname=contact.name)
    db.session.commit()

    return success_response(contact.to_dict(), message='Contact created',
                            http_code=201)


@supportteams_bp.route('/<int:team_id>/contacts/<int:contact_id>',
                       methods=['PUT'])
@jwt_required()
@require_role('admin')
def update_contact(team_id: int, contact_id: int):
    """Update a support-team contact."""
    contact = SupportTeamContact.query.filter_by(
        contactid=contact_id, supportteamid=team_id).first()
    if not contact:
        return error_response(ErrorCodes.NOT_FOUND, 'Contact not found',
                              http_code=404)

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

    for key in ['name', 'sso', 'sortorder', 'isactive']:
        if key in data:
            setattr(contact, key, data[key])

    apply_import_timestamps(contact, data)
    AuditLog.log('updated', 'SupportTeamContact', entityid=contact.contactid,
                 entityname=contact.name)
    db.session.commit()

    return success_response(contact.to_dict(), message='Contact updated')


@supportteams_bp.route('/<int:team_id>/contacts/<int:contact_id>',
                       methods=['DELETE'])
@jwt_required()
@require_role('admin')
def delete_contact(team_id: int, contact_id: int):
    """Delete a support-team contact."""
    contact = SupportTeamContact.query.filter_by(
        contactid=contact_id, supportteamid=team_id).first()
    if not contact:
        return error_response(ErrorCodes.NOT_FOUND, 'Contact not found',
                              http_code=404)

    AuditLog.log('deleted', 'SupportTeamContact', entityid=contact.contactid,
                 entityname=contact.name)
    db.session.delete(contact)
    db.session.commit()

    return success_response(message='Contact deleted')
