"""
GBP Audit API Routes - API blueprint

Migrated from app.py as part of the blueprint refactoring.
Contains API routes for Google Business Profile audit functionality.
"""

import logging
from datetime import datetime

from flask import jsonify, request, current_app
from flask_login import current_user, login_required

from database import SessionLocal, Company
from . import bp

logger = logging.getLogger(__name__)


# Check if GBP audit service is available
try:
    from gbp_audit_service import (
        GBPAuditResult,
        audit_company as gbp_audit_company,
        get_company_audit as gbp_get_company_audit,
        fetch_google_business_data as gbp_fetch_google_data
    )
    GBP_AUDIT_AVAILABLE = True
    GBP_AUDIT_VERSION = '1.0'
except ImportError:
    GBP_AUDIT_AVAILABLE = False
    GBP_AUDIT_VERSION = None


def get_limiter():
    """Get rate limiter from current app."""
    return current_app.extensions.get('limiter')


# ============================================================
# GBP AUDIT API ROUTES
# ============================================================

@bp.route('/gbp/audit/health')
def api_gbp_audit_health():
    """
    API: Health check for GBP audit service.

    Returns service status and version information.
    Used by monitoring systems to verify service availability.
    """
    if GBP_AUDIT_AVAILABLE:
        return jsonify({
            'status': 'ok',
            'service': 'gbp_audit',
            'version': GBP_AUDIT_VERSION,
            'available': True
        }), 200
    else:
        return jsonify({
            'status': 'unavailable',
            'service': 'gbp_audit',
            'available': False,
            'error': 'GBP audit service not loaded'
        }), 503


@bp.route('/gbp/audit', methods=['GET'])
def api_gbp_audit_get():
    """
    API: Get GBP audit results for a company.

    Query parameters:
    - company_id: Company ID (integer) OR
    - slug: Company slug (string)

    Returns:
    - Latest audit results with completeness score and recommendations
    - 404 if company not found
    - 404 if no audit exists for the company

    Example: GET /api/gbp/audit?company_id=26
    Example: GET /api/gbp/audit?slug=pixlab-sp-z-o-o
    """
    if not GBP_AUDIT_AVAILABLE:
        return jsonify({
            'success': False,
            'error': 'Usługa audytu GBP jest niedostępna.'
        }), 503

    company_id = request.args.get('company_id', type=int)
    slug = request.args.get('slug')

    if not company_id and not slug:
        return jsonify({
            'success': False,
            'error': 'Podaj company_id lub slug firmy.'
        }), 400

    db = SessionLocal()
    try:
        # Find company
        if company_id:
            company = db.query(Company).filter_by(id=company_id, status='active').first()
        else:
            company = db.query(Company).filter_by(slug=slug, status='active').first()

        if not company:
            return jsonify({
                'success': False,
                'error': 'Firma nie znaleziona lub nieaktywna.'
            }), 404

        # Get latest audit
        audit = gbp_get_company_audit(db, company.id)

        if not audit:
            return jsonify({
                'success': False,
                'error': f'Brak wyników audytu GBP dla firmy "{company.name}". Uruchom audyt używając POST /api/gbp/audit.',
                'company_id': company.id,
                'company_name': company.name
            }), 404

        # Build response
        return jsonify({
            'success': True,
            'company_id': company.id,
            'company_name': company.name,
            'company_slug': company.slug,
            'audit': {
                'id': audit.id,
                'audit_date': audit.audit_date.isoformat() if audit.audit_date else None,
                'completeness_score': audit.completeness_score,
                'score_category': audit.score_category,
                'fields_status': audit.fields_status,
                'recommendations': audit.recommendations,
                'has_name': audit.has_name,
                'has_address': audit.has_address,
                'has_phone': audit.has_phone,
                'has_website': audit.has_website,
                'has_hours': audit.has_hours,
                'has_categories': audit.has_categories,
                'has_photos': audit.has_photos,
                'has_description': audit.has_description,
                'has_services': audit.has_services,
                'has_reviews': audit.has_reviews,
                'photo_count': audit.photo_count,
                'review_count': audit.review_count,
                'average_rating': float(audit.average_rating) if audit.average_rating else None,
                'google_place_id': audit.google_place_id,
                'audit_source': audit.audit_source,
                'audit_version': audit.audit_version
            }
        }), 200

    except Exception as e:
        logger.error(f"Error fetching GBP audit: {e}")
        return jsonify({
            'success': False,
            'error': f'Błąd podczas pobierania audytu: {str(e)}'
        }), 500
    finally:
        db.close()


@bp.route('/gbp/audit/<slug>')
def api_gbp_audit_by_slug(slug):
    """
    API: Get GBP audit results for a company by slug.
    Convenience endpoint that uses slug from URL path.

    Example: GET /api/gbp/audit/pixlab-sp-z-o-o
    """
    if not GBP_AUDIT_AVAILABLE:
        return jsonify({
            'success': False,
            'error': 'Usługa audytu GBP jest niedostępna.'
        }), 503

    db = SessionLocal()
    try:
        company = db.query(Company).filter_by(slug=slug, status='active').first()

        if not company:
            return jsonify({
                'success': False,
                'error': f'Firma o slug "{slug}" nie znaleziona.'
            }), 404

        audit = gbp_get_company_audit(db, company.id)

        if not audit:
            return jsonify({
                'success': False,
                'error': f'Brak wyników audytu GBP dla firmy "{company.name}".',
                'company_id': company.id,
                'company_name': company.name
            }), 404

        return jsonify({
            'success': True,
            'company_id': company.id,
            'company_name': company.name,
            'company_slug': company.slug,
            'audit': {
                'id': audit.id,
                'audit_date': audit.audit_date.isoformat() if audit.audit_date else None,
                'completeness_score': audit.completeness_score,
                'score_category': audit.score_category,
                'fields_status': audit.fields_status,
                'recommendations': audit.recommendations,
                'photo_count': audit.photo_count,
                'review_count': audit.review_count,
                'average_rating': float(audit.average_rating) if audit.average_rating else None
            }
        }), 200

    finally:
        db.close()


@bp.route('/gbp/audit', methods=['POST'])
@login_required
def api_gbp_audit_trigger():
    """
    API: Run GBP audit for a company.

    This endpoint runs a completeness audit for Google Business Profile data,
    checking fields like name, address, phone, website, hours, categories,
    photos, description, services, and reviews.

    Request JSON body:
    - company_id: Company ID (integer) OR
    - slug: Company slug (string)
    - save: Whether to save results to database (default: true)

    Returns:
    - Success: Audit results with completeness score and recommendations
    - Error: Error message with status code

    Access:
    - Members can audit their own company
    - Admins can audit any company

    Rate limited to 20 requests per hour per user.
    """
    if not GBP_AUDIT_AVAILABLE:
        return jsonify({
            'success': False,
            'error': 'Usługa audytu GBP jest niedostępna. Sprawdź konfigurację serwera.'
        }), 503

    # Parse request data
    data = request.get_json()
    if not data:
        return jsonify({
            'success': False,
            'error': 'Brak danych w żądaniu. Podaj company_id lub slug.'
        }), 400

    company_id = data.get('company_id')
    slug = data.get('slug')
    save_result = data.get('save', True)

    if not company_id and not slug:
        return jsonify({
            'success': False,
            'error': 'Podaj company_id lub slug firmy do audytu.'
        }), 400

    db = SessionLocal()
    try:
        # Find company by ID or slug
        if company_id:
            company = db.query(Company).filter_by(id=company_id, status='active').first()
        else:
            company = db.query(Company).filter_by(slug=slug, status='active').first()

        if not company:
            return jsonify({
                'success': False,
                'error': 'Firma nie znaleziona lub nieaktywna.'
            }), 404

        # Check access: users with company edit rights can audit
        if not current_user.can_edit_company(company.id):
            return jsonify({
                'success': False,
                'error': 'Brak uprawnień. Możesz audytować tylko własną firmę.'
            }), 403

        logger.info(f"GBP audit triggered by {current_user.email} for company: {company.name} (ID: {company.id})")

        # Option to fetch fresh Google data before audit
        fetch_google = data.get('fetch_google', True)
        force_refresh = data.get('force_refresh', False)

        try:
            # Step 1: Fetch fresh Google Business data (if enabled)
            fetch_result = None
            if fetch_google:
                logger.info(f"Fetching Google Business data for company {company.id}...")
                fetch_result = gbp_fetch_google_data(db, company.id, force_refresh=force_refresh)
                if not fetch_result.get('success') and not fetch_result.get('data', {}).get('cached'):
                    # Log warning but continue with audit
                    logger.warning(f"Google fetch warning for company {company.id}: {fetch_result.get('error')}")

            # Step 2: Run the audit
            result = gbp_audit_company(db, company.id, save=save_result)

            # Build field status for response
            fields_response = {}
            for field_name, field_status in result.fields.items():
                fields_response[field_name] = {
                    'status': field_status.status,
                    'value': str(field_status.value) if field_status.value is not None else None,
                    'score': field_status.score,
                    'max_score': field_status.max_score,
                    'recommendation': field_status.recommendation
                }

            # Determine score category
            score = result.completeness_score
            if score >= 90:
                score_category = 'excellent'
            elif score >= 70:
                score_category = 'good'
            elif score >= 50:
                score_category = 'needs_work'
            else:
                score_category = 'poor'

            response_data = {
                'success': True,
                'message': f'Audyt GBP dla firmy "{company.name}" został zakończony pomyślnie.',
                'company_id': company.id,
                'company_name': company.name,
                'company_slug': company.slug,
                'audit_version': GBP_AUDIT_VERSION,
                'triggered_by': current_user.email,
                'triggered_at': datetime.now().isoformat(),
                'saved': save_result,
                'audit': {
                    'completeness_score': result.completeness_score,
                    'score_category': score_category,
                    'fields_status': fields_response,
                    'recommendations': result.recommendations,
                    'photo_count': result.photo_count,
                    'logo_present': result.logo_present,
                    'cover_photo_present': result.cover_photo_present,
                    'review_count': result.review_count,
                    'average_rating': float(result.average_rating) if result.average_rating else None,
                    'google_place_id': result.google_place_id
                }
            }

            # Include Google fetch results if performed
            if fetch_result:
                response_data['google_fetch'] = {
                    'success': fetch_result.get('success', False),
                    'steps': fetch_result.get('steps', []),
                    'data': fetch_result.get('data', {}),
                    'error': fetch_result.get('error')
                }

            return jsonify(response_data), 200

        except ValueError as e:
            return jsonify({
                'success': False,
                'error': str(e),
                'company_id': company.id if company else None
            }), 400
        except Exception as e:
            logger.error(f"GBP audit error for company {company.id}: {e}")
            return jsonify({
                'success': False,
                'error': f'Błąd podczas wykonywania audytu: {str(e)}',
                'company_id': company.id,
                'company_name': company.name
            }), 500

    finally:
        db.close()
