"""
GBP Audit Service for Norda Biznes Hub
=======================================

Google Business Profile completeness audit service with:
- Field-by-field completeness checking
- Weighted scoring algorithm
- AI-powered recommendations (via Gemini)
- Historical tracking

Inspired by Localo.com audit features.

Author: Norda Biznes Development Team
Created: 2026-01-08
"""

import json
import logging
from dataclasses import dataclass, field
from datetime import datetime
from decimal import Decimal
from typing import Dict, List, Optional, Any

from sqlalchemy.orm import Session

from database import Company, GBPAudit, CompanyWebsiteAnalysis, SessionLocal
import gemini_service

# Configure logging
logger = logging.getLogger(__name__)


# Field weights for completeness scoring (total = 100)
FIELD_WEIGHTS = {
    'name': 10,           # Business name - essential
    'address': 10,        # Full address - essential for local SEO
    'phone': 8,           # Contact phone - important
    'website': 8,         # Business website - important
    'hours': 8,           # Opening hours - important for customers
    'categories': 10,     # Business categories - essential for discovery
    'photos': 15,         # Photos - high impact on engagement
    'description': 12,    # Business description - important for SEO
    'services': 10,       # Services list - important for discovery
    'reviews': 9,         # Review presence and rating - trust factor
}

# Photo requirements for optimal GBP profile
PHOTO_REQUIREMENTS = {
    'minimum': 3,         # Minimum photos for basic completeness
    'recommended': 10,    # Recommended for good profile
    'optimal': 25,        # Optimal for excellent profile
}

# Review thresholds
REVIEW_THRESHOLDS = {
    'minimum': 1,         # At least 1 review
    'good': 5,            # Good number of reviews
    'excellent': 20,      # Excellent review count
}

# Google Place Types to Polish translations
# Source: https://developers.google.com/maps/documentation/places/web-service/supported_types
GOOGLE_TYPES_PL = {
    # Automotive
    'car_dealer': 'Salon samochodowy',
    'car_rental': 'Wynajem samochodów',
    'car_repair': 'Warsztat samochodowy',
    'car_wash': 'Myjnia samochodowa',
    'electric_vehicle_charging_station': 'Stacja ładowania EV',
    'gas_station': 'Stacja paliw',
    'parking': 'Parking',
    'rest_stop': 'Miejsce odpoczynku',

    # Business
    'farm': 'Gospodarstwo rolne',

    # Culture
    'art_gallery': 'Galeria sztuki',
    'museum': 'Muzeum',
    'performing_arts_theater': 'Teatr',

    # Education
    'library': 'Biblioteka',
    'preschool': 'Przedszkole',
    'primary_school': 'Szkoła podstawowa',
    'school': 'Szkoła',
    'secondary_school': 'Szkoła średnia',
    'university': 'Uniwersytet',

    # Entertainment and Recreation
    'amusement_center': 'Centrum rozrywki',
    'amusement_park': 'Park rozrywki',
    'aquarium': 'Akwarium',
    'banquet_hall': 'Sala bankietowa',
    'bowling_alley': 'Kręgielnia',
    'casino': 'Kasyno',
    'community_center': 'Centrum społeczne',
    'convention_center': 'Centrum konferencyjne',
    'cultural_center': 'Centrum kultury',
    'dog_park': 'Park dla psów',
    'event_venue': 'Miejsce eventowe',
    'hiking_area': 'Szlak turystyczny',
    'historical_landmark': 'Zabytek',
    'marina': 'Przystań',
    'movie_rental': 'Wypożyczalnia filmów',
    'movie_theater': 'Kino',
    'national_park': 'Park narodowy',
    'night_club': 'Klub nocny',
    'park': 'Park',
    'tourist_attraction': 'Atrakcja turystyczna',
    'visitor_center': 'Centrum informacyjne',
    'wedding_venue': 'Sala weselna',
    'zoo': 'Zoo',

    # Finance
    'accounting': 'Biuro rachunkowe',
    'atm': 'Bankomat',
    'bank': 'Bank',

    # Food and Drink
    'american_restaurant': 'Restauracja amerykańska',
    'bakery': 'Piekarnia',
    'bar': 'Bar',
    'barbecue_restaurant': 'Restauracja BBQ',
    'brazilian_restaurant': 'Restauracja brazylijska',
    'breakfast_restaurant': 'Restauracja śniadaniowa',
    'brunch_restaurant': 'Restauracja brunchowa',
    'cafe': 'Kawiarnia',
    'chinese_restaurant': 'Restauracja chińska',
    'coffee_shop': 'Kawiarnia',
    'fast_food_restaurant': 'Fast food',
    'french_restaurant': 'Restauracja francuska',
    'greek_restaurant': 'Restauracja grecka',
    'hamburger_restaurant': 'Burgery',
    'ice_cream_shop': 'Lodziarnia',
    'indian_restaurant': 'Restauracja indyjska',
    'indonesian_restaurant': 'Restauracja indonezyjska',
    'italian_restaurant': 'Restauracja włoska',
    'japanese_restaurant': 'Restauracja japońska',
    'korean_restaurant': 'Restauracja koreańska',
    'lebanese_restaurant': 'Restauracja libańska',
    'meal_delivery': 'Dostawa jedzenia',
    'meal_takeaway': 'Jedzenie na wynos',
    'mediterranean_restaurant': 'Restauracja śródziemnomorska',
    'mexican_restaurant': 'Restauracja meksykańska',
    'middle_eastern_restaurant': 'Restauracja bliskowschodnia',
    'pizza_restaurant': 'Pizzeria',
    'ramen_restaurant': 'Ramen',
    'restaurant': 'Restauracja',
    'sandwich_shop': 'Kanapki',
    'seafood_restaurant': 'Owoce morza',
    'spanish_restaurant': 'Restauracja hiszpańska',
    'steak_house': 'Steakhouse',
    'sushi_restaurant': 'Sushi',
    'thai_restaurant': 'Restauracja tajska',
    'turkish_restaurant': 'Restauracja turecka',
    'vegan_restaurant': 'Restauracja wegańska',
    'vegetarian_restaurant': 'Restauracja wegetariańska',
    'vietnamese_restaurant': 'Restauracja wietnamska',

    # Government
    'city_hall': 'Ratusz',
    'courthouse': 'Sąd',
    'embassy': 'Ambasada',
    'fire_station': 'Straż pożarna',
    'local_government_office': 'Urząd',
    'police': 'Policja',
    'post_office': 'Poczta',

    # Health and Wellness
    'dental_clinic': 'Klinika stomatologiczna',
    'dentist': 'Dentysta',
    'doctor': 'Lekarz',
    'drugstore': 'Apteka',
    'hospital': 'Szpital',
    'medical_lab': 'Laboratorium medyczne',
    'pharmacy': 'Apteka',
    'physiotherapist': 'Fizjoterapeuta',
    'spa': 'Spa',

    # Lodging
    'bed_and_breakfast': 'Nocleg ze śniadaniem',
    'campground': 'Pole namiotowe',
    'camping_cabin': 'Domek kempingowy',
    'cottage': 'Domek letniskowy',
    'extended_stay_hotel': 'Hotel długoterminowy',
    'farmstay': 'Agroturystyka',
    'guest_house': 'Pensjonat',
    'hostel': 'Hostel',
    'hotel': 'Hotel',
    'lodging': 'Nocleg',
    'motel': 'Motel',
    'private_guest_room': 'Pokój gościnny',
    'resort_hotel': 'Hotel resortowy',
    'rv_park': 'Park dla kamperów',

    # Places of Worship
    'church': 'Kościół',
    'hindu_temple': 'Świątynia hinduska',
    'mosque': 'Meczet',
    'synagogue': 'Synagoga',

    # Services
    'barber_shop': 'Fryzjer męski',
    'beauty_salon': 'Salon kosmetyczny',
    'cemetery': 'Cmentarz',
    'child_care_agency': 'Opieka nad dziećmi',
    'consultant': 'Konsultant',
    'courier_service': 'Usługi kurierskie',
    'electrician': 'Elektryk',
    'florist': 'Kwiaciarnia',
    'funeral_home': 'Dom pogrzebowy',
    'hair_care': 'Fryzjer',
    'hair_salon': 'Salon fryzjerski',
    'insurance_agency': 'Agencja ubezpieczeniowa',
    'laundry': 'Pralnia',
    'lawyer': 'Prawnik',
    'locksmith': 'Ślusarz',
    'moving_company': 'Firma przeprowadzkowa',
    'painter': 'Malarz',
    'plumber': 'Hydraulik',
    'real_estate_agency': 'Agencja nieruchomości',
    'roofing_contractor': 'Dekarz',
    'storage': 'Magazyn',
    'tailor': 'Krawiec',
    'telecommunications_service_provider': 'Telekomunikacja',
    'travel_agency': 'Biuro podróży',
    'veterinary_care': 'Weterynarz',

    # Shopping
    'auto_parts_store': 'Sklep z częściami',
    'bicycle_store': 'Sklep rowerowy',
    'book_store': 'Księgarnia',
    'cell_phone_store': 'Sklep z telefonami',
    'clothing_store': 'Sklep odzieżowy',
    'convenience_store': 'Sklep spożywczy',
    'department_store': 'Dom towarowy',
    'discount_store': 'Sklep z przecenami',
    'electronics_store': 'Sklep elektroniczny',
    'furniture_store': 'Sklep meblowy',
    'gift_shop': 'Sklep z upominkami',
    'grocery_store': 'Sklep spożywczy',
    'hardware_store': 'Sklep z narzędziami',
    'home_goods_store': 'Sklep z artykułami domowymi',
    'home_improvement_store': 'Market budowlany',
    'jewelry_store': 'Jubiler',
    'liquor_store': 'Sklep monopolowy',
    'market': 'Targ',
    'pet_store': 'Sklep zoologiczny',
    'shoe_store': 'Sklep obuwniczy',
    'shopping_mall': 'Centrum handlowe',
    'sporting_goods_store': 'Sklep sportowy',
    'store': 'Sklep',
    'supermarket': 'Supermarket',
    'wholesaler': 'Hurtownia',

    # Sports
    'athletic_field': 'Boisko sportowe',
    'fitness_center': 'Siłownia',
    'golf_course': 'Pole golfowe',
    'gym': 'Siłownia',
    'playground': 'Plac zabaw',
    'ski_resort': 'Ośrodek narciarski',
    'sports_club': 'Klub sportowy',
    'sports_complex': 'Kompleks sportowy',
    'stadium': 'Stadion',
    'swimming_pool': 'Basen',

    # Transportation
    'airport': 'Lotnisko',
    'bus_station': 'Dworzec autobusowy',
    'bus_stop': 'Przystanek autobusowy',
    'ferry_terminal': 'Terminal promowy',
    'heliport': 'Lądowisko helikopterów',
    'light_rail_station': 'Stacja kolejki',
    'park_and_ride': 'Park & Ride',
    'subway_station': 'Stacja metra',
    'taxi_stand': 'Postój taksówek',
    'train_station': 'Dworzec kolejowy',
    'transit_depot': 'Zajezdnia',
    'transit_station': 'Stacja przesiadkowa',
    'truck_stop': 'Parking dla TIR-ów',

    # Generic types (often returned by Google)
    'establishment': 'Firma',
    'point_of_interest': 'Punkt zainteresowania',
    'general_contractor': 'Firma budowlana',
    'roofing_contractor': 'Dekarz',
    'hvac_contractor': 'Klimatyzacja i ogrzewanie',
    'plumber': 'Hydraulik',
    'electrician': 'Elektryk',
    'contractor': 'Wykonawca',
    'construction_company': 'Firma budowlana',
    'industrial_area': 'Strefa przemysłowa',
    'office': 'Biuro',
    'food': 'Gastronomia',
    'health': 'Zdrowie',
    'finance': 'Finanse',
    'political': 'Instytucja polityczna',
    'place_of_worship': 'Miejsce kultu',
    'natural_feature': 'Obiekt przyrodniczy',
    'locality': 'Miejscowość',
    'sublocality': 'Dzielnica',
    'neighborhood': 'Okolica',
    'premise': 'Lokal',
    'subpremise': 'Podlokal',
    'route': 'Trasa',
    'street_address': 'Adres',
    'floor': 'Piętro',
    'room': 'Pokój',
    'postal_code': 'Kod pocztowy',
    'country': 'Kraj',
    'administrative_area_level_1': 'Województwo',
    'administrative_area_level_2': 'Powiat',
}


@dataclass
class FieldStatus:
    """Status of a single GBP field"""
    field_name: str
    status: str  # 'complete', 'partial', 'missing'
    value: Optional[Any] = None
    score: float = 0.0
    max_score: float = 0.0
    recommendation: Optional[str] = None
    details: Optional[Dict[str, Any]] = None  # Additional field-specific details


@dataclass
class AuditResult:
    """Complete GBP audit result"""
    company_id: int
    completeness_score: int
    fields: Dict[str, FieldStatus] = field(default_factory=dict)
    recommendations: List[Dict[str, Any]] = field(default_factory=list)
    photo_count: int = 0
    logo_present: bool = False
    cover_photo_present: bool = False
    review_count: int = 0
    average_rating: Optional[Decimal] = None
    google_place_id: Optional[str] = None
    google_maps_url: Optional[str] = None
    audit_errors: Optional[str] = None


class GBPAuditService:
    """Service for auditing Google Business Profile completeness"""

    def __init__(self, db: Session):
        """
        Initialize GBP Audit service.

        Args:
            db: SQLAlchemy database session
        """
        self.db = db

    def audit_company(self, company_id: int) -> AuditResult:
        """
        Run full GBP audit for a company.

        Args:
            company_id: ID of the company to audit

        Returns:
            AuditResult with completeness score and field details
        """
        company = self.db.query(Company).filter(Company.id == company_id).first()
        if not company:
            raise ValueError(f"Company with id {company_id} not found")

        # Get latest website analysis for Google Business data
        website_analysis = self.db.query(CompanyWebsiteAnalysis).filter(
            CompanyWebsiteAnalysis.company_id == company_id
        ).order_by(CompanyWebsiteAnalysis.analyzed_at.desc()).first()

        # Audit each field
        fields = {}
        total_score = 0.0
        recommendations = []

        # Name check (uses Google data)
        fields['name'] = self._check_name(company, website_analysis)
        total_score += fields['name'].score

        # Address check (uses Google data)
        fields['address'] = self._check_address(company, website_analysis)
        total_score += fields['address'].score

        # Phone check (uses Google data)
        fields['phone'] = self._check_phone(company, website_analysis)
        total_score += fields['phone'].score

        # Website check (uses Google data)
        fields['website'] = self._check_website(company, website_analysis)
        total_score += fields['website'].score

        # Hours check (uses Google data)
        fields['hours'] = self._check_hours(company, website_analysis)
        total_score += fields['hours'].score

        # Categories check (uses Google data - google_types)
        fields['categories'] = self._check_categories(company, website_analysis)
        total_score += fields['categories'].score

        # Photos check (uses Google data)
        fields['photos'] = self._check_photos(company, website_analysis)
        total_score += fields['photos'].score

        # Description check - Google API doesn't provide owner description
        fields['description'] = self._check_description(company)
        total_score += fields['description'].score

        # Services check
        fields['services'] = self._check_services(company)
        total_score += fields['services'].score

        # Reviews check (from website analysis)
        fields['reviews'] = self._check_reviews(company, website_analysis)
        total_score += fields['reviews'].score

        # Build recommendations from fields with issues
        for field_name, field_status in fields.items():
            if field_status.recommendation:
                priority = self._get_priority(field_status)
                recommendations.append({
                    'priority': priority,
                    'field': field_name,
                    'recommendation': field_status.recommendation,
                    'impact': FIELD_WEIGHTS.get(field_name, 0)
                })

        # Sort recommendations by priority and impact
        priority_order = {'high': 0, 'medium': 1, 'low': 2}
        recommendations.sort(key=lambda x: (priority_order.get(x['priority'], 3), -x['impact']))

        # Extract Google Business data from website analysis
        google_place_id = None
        google_maps_url = None
        review_count = 0
        average_rating = None

        if website_analysis:
            google_place_id = website_analysis.google_place_id
            google_maps_url = website_analysis.google_maps_url
            review_count = website_analysis.google_reviews_count or 0
            average_rating = website_analysis.google_rating

        # Create result
        result = AuditResult(
            company_id=company_id,
            completeness_score=round(total_score),
            fields=fields,
            recommendations=recommendations,
            photo_count=fields['photos'].value if isinstance(fields['photos'].value, int) else 0,
            logo_present=False,  # Would need specific logo detection
            cover_photo_present=False,  # Would need specific cover detection
            review_count=review_count,
            average_rating=average_rating,
            google_place_id=google_place_id,
            google_maps_url=google_maps_url
        )

        return result

    def save_audit(self, result: AuditResult, source: str = 'manual') -> GBPAudit:
        """
        Save audit result to database.

        Args:
            result: AuditResult to save
            source: Audit source ('manual', 'automated', 'api')

        Returns:
            Saved GBPAudit record
        """
        # Convert fields to JSON-serializable format
        fields_status = {}
        for name, field_status in result.fields.items():
            # Keep dict values as-is for JSON serialization (e.g., opening hours)
            # Convert other complex types to string
            if field_status.value is None:
                serialized_value = None
            elif isinstance(field_status.value, (dict, list)):
                serialized_value = field_status.value  # Keep as dict/list for JSON
            elif isinstance(field_status.value, (int, float, bool)):
                serialized_value = field_status.value  # Keep primitives as-is
            else:
                serialized_value = str(field_status.value)

            fields_status[name] = {
                'status': field_status.status,
                'value': serialized_value,
                'score': field_status.score,
                'max_score': field_status.max_score,
                'details': field_status.details
            }

        # Create audit record
        audit = GBPAudit(
            company_id=result.company_id,
            audit_date=datetime.now(),
            completeness_score=result.completeness_score,
            fields_status=fields_status,
            recommendations=result.recommendations,
            has_name=result.fields.get('name', FieldStatus('name', 'missing')).status == 'complete',
            has_address=result.fields.get('address', FieldStatus('address', 'missing')).status == 'complete',
            has_phone=result.fields.get('phone', FieldStatus('phone', 'missing')).status == 'complete',
            has_website=result.fields.get('website', FieldStatus('website', 'missing')).status == 'complete',
            has_hours=result.fields.get('hours', FieldStatus('hours', 'missing')).status == 'complete',
            has_categories=result.fields.get('categories', FieldStatus('categories', 'missing')).status == 'complete',
            has_photos=result.fields.get('photos', FieldStatus('photos', 'missing')).status in ['complete', 'partial'],
            has_description=result.fields.get('description', FieldStatus('description', 'missing')).status == 'complete',
            has_services=result.fields.get('services', FieldStatus('services', 'missing')).status == 'complete',
            has_reviews=result.fields.get('reviews', FieldStatus('reviews', 'missing')).status in ['complete', 'partial'],
            photo_count=result.photo_count,
            logo_present=result.logo_present,
            cover_photo_present=result.cover_photo_present,
            review_count=result.review_count,
            average_rating=result.average_rating,
            google_place_id=result.google_place_id,
            google_maps_url=result.google_maps_url,
            audit_source=source,
            audit_version='1.0',
            audit_errors=result.audit_errors
        )

        self.db.add(audit)
        self.db.commit()
        self.db.refresh(audit)

        logger.info(f"GBP audit saved for company {result.company_id}: score={result.completeness_score}")
        return audit

    def get_latest_audit(self, company_id: int) -> Optional[GBPAudit]:
        """
        Get the most recent audit for a company.

        Args:
            company_id: Company ID

        Returns:
            Latest GBPAudit or None
        """
        return self.db.query(GBPAudit).filter(
            GBPAudit.company_id == company_id
        ).order_by(GBPAudit.audit_date.desc()).first()

    def get_audit_history(self, company_id: int, limit: int = 10) -> List[GBPAudit]:
        """
        Get audit history for a company.

        Args:
            company_id: Company ID
            limit: Maximum number of audits to return

        Returns:
            List of GBPAudit records ordered by date descending
        """
        return self.db.query(GBPAudit).filter(
            GBPAudit.company_id == company_id
        ).order_by(GBPAudit.audit_date.desc()).limit(limit).all()

    # === Field Check Methods ===

    def _check_name(self, company: Company, analysis: Optional[CompanyWebsiteAnalysis]) -> FieldStatus:
        """Check business name completeness - uses Google data"""
        max_score = FIELD_WEIGHTS['name']

        # Use Google name if available, fallback to NordaBiz
        name = analysis.google_name if analysis and analysis.google_name else company.name

        if name and len(name.strip()) >= 3:
            return FieldStatus(
                field_name='name',
                status='complete',
                value=name,
                score=max_score,
                max_score=max_score
            )

        return FieldStatus(
            field_name='name',
            status='missing',
            score=0,
            max_score=max_score,
            recommendation='Dodaj nazwę firmy do wizytówki Google. Nazwa powinna być oficjalną nazwą firmy.'
        )

    def _check_address(self, company: Company, analysis: Optional[CompanyWebsiteAnalysis]) -> FieldStatus:
        """Check address completeness - uses Google data"""
        max_score = FIELD_WEIGHTS['address']

        # Use Google address if available
        google_address = analysis.google_address if analysis else None

        if google_address and len(google_address.strip()) >= 10:
            return FieldStatus(
                field_name='address',
                status='complete',
                value=google_address,
                score=max_score,
                max_score=max_score
            )

        # Fallback to NordaBiz data
        has_street = bool(company.address_street)
        has_city = bool(company.address_city)

        if has_city or has_street:
            partial_score = max_score * 0.5
            return FieldStatus(
                field_name='address',
                status='partial',
                value=company.address_city or company.address_street,
                score=partial_score,
                max_score=max_score,
                recommendation='Uzupełnij pełny adres firmy w Google Business Profile.'
            )

        return FieldStatus(
            field_name='address',
            status='missing',
            score=0,
            max_score=max_score,
            recommendation='Dodaj adres firmy do wizytówki Google. Pełny adres jest kluczowy dla lokalnego SEO.'
        )

    def _check_phone(self, company: Company, analysis: Optional[CompanyWebsiteAnalysis]) -> FieldStatus:
        """Check phone number presence - uses Google data"""
        max_score = FIELD_WEIGHTS['phone']

        # Use Google phone if available
        phone = analysis.google_phone if analysis and analysis.google_phone else company.phone

        if phone and len(phone.strip()) >= 9:
            return FieldStatus(
                field_name='phone',
                status='complete',
                value=phone,
                score=max_score,
                max_score=max_score
            )

        return FieldStatus(
            field_name='phone',
            status='missing',
            score=0,
            max_score=max_score,
            recommendation='Dodaj numer telefonu do wizytówki Google. Klienci oczekują możliwości bezpośredniego kontaktu.'
        )

    def _check_website(self, company: Company, analysis: Optional[CompanyWebsiteAnalysis]) -> FieldStatus:
        """Check website presence - uses Google data"""
        max_score = FIELD_WEIGHTS['website']

        # Use Google website if available
        website = analysis.google_website if analysis and analysis.google_website else company.website

        if website and website.strip().startswith(('http://', 'https://')):
            return FieldStatus(
                field_name='website',
                status='complete',
                value=website,
                score=max_score,
                max_score=max_score
            )

        if website:
            # Has website but might not be properly formatted
            return FieldStatus(
                field_name='website',
                status='partial',
                value=website,
                score=max_score * 0.7,
                max_score=max_score,
                recommendation='Upewnij się, że adres strony w Google Business Profile zawiera protokół (https://).'
            )

        return FieldStatus(
            field_name='website',
            status='missing',
            score=0,
            max_score=max_score,
            recommendation='Dodaj stronę internetową do wizytówki Google. Link do strony zwiększa wiarygodność i ruch.'
        )

    def _check_hours(self, company: Company, analysis: Optional[CompanyWebsiteAnalysis]) -> FieldStatus:
        """Check opening hours presence"""
        max_score = FIELD_WEIGHTS['hours']

        # Check if we have opening hours from Google Business Profile
        if analysis and analysis.google_opening_hours:
            return FieldStatus(
                field_name='hours',
                status='complete',
                value=analysis.google_opening_hours,
                score=max_score,
                max_score=max_score
            )

        return FieldStatus(
            field_name='hours',
            status='missing',
            score=0,
            max_score=max_score,
            recommendation='Dodaj godziny otwarcia firmy. Klienci chcą wiedzieć, kiedy mogą Cię odwiedzić.'
        )

    def _check_categories(self, company: Company, analysis: Optional[CompanyWebsiteAnalysis]) -> FieldStatus:
        """Check business category completeness - uses Google data"""
        max_score = FIELD_WEIGHTS['categories']

        # Use Google types if available
        google_types = analysis.google_types if analysis and analysis.google_types else None

        if google_types and len(google_types) > 0:
            # Translate Google types to Polish using GOOGLE_TYPES_PL dictionary
            # Fallback to formatted English if translation not available
            formatted_types = []
            for t in google_types[:3]:
                if t in GOOGLE_TYPES_PL:
                    formatted_types.append(GOOGLE_TYPES_PL[t])
                else:
                    # Fallback: remove underscores, title case
                    formatted_types.append(t.replace('_', ' ').title())

            return FieldStatus(
                field_name='categories',
                status='complete',
                value=', '.join(formatted_types),
                score=max_score,
                max_score=max_score
            )

        # Fallback to NordaBiz category
        if company.category_id and company.category:
            return FieldStatus(
                field_name='categories',
                status='partial',
                value=company.category.name if company.category else None,
                score=max_score * 0.5,
                max_score=max_score,
                recommendation='Dodaj kategorie w Google Business Profile. Kategorie z Google są ważniejsze dla SEO niż dane lokalne.'
            )

        return FieldStatus(
            field_name='categories',
            status='missing',
            score=0,
            max_score=max_score,
            recommendation='Wybierz główną kategorię działalności w Google Business Profile. Kategoria pomaga klientom znaleźć Twoją firmę.'
        )

    def _check_photos(self, company: Company, analysis: Optional[CompanyWebsiteAnalysis]) -> FieldStatus:
        """Check photo completeness"""
        max_score = FIELD_WEIGHTS['photos']

        # Get Google Business Profile photo count from website analysis
        photo_count = 0
        if analysis and analysis.google_photos_count:
            photo_count = analysis.google_photos_count

        if photo_count >= PHOTO_REQUIREMENTS['recommended']:
            return FieldStatus(
                field_name='photos',
                status='complete',
                value=photo_count,
                score=max_score,
                max_score=max_score
            )

        if photo_count >= PHOTO_REQUIREMENTS['minimum']:
            partial_score = max_score * (photo_count / PHOTO_REQUIREMENTS['recommended'])
            return FieldStatus(
                field_name='photos',
                status='partial',
                value=photo_count,
                score=min(partial_score, max_score * 0.7),
                max_score=max_score,
                recommendation=f'Dodaj więcej zdjęć firmy. Zalecane minimum to {PHOTO_REQUIREMENTS["recommended"]} zdjęć.'
            )

        return FieldStatus(
            field_name='photos',
            status='missing',
            value=photo_count,
            score=0,
            max_score=max_score,
            recommendation='Dodaj zdjęcia firmy (logo, wnętrze, zespół, produkty). Wizytówki ze zdjęciami mają 42% więcej zapytań o wskazówki dojazdu.'
        )

    def _check_description(self, company: Company) -> FieldStatus:
        """Check business description completeness"""
        max_score = FIELD_WEIGHTS['description']

        # Check short and full descriptions
        desc = company.description_full or company.description_short

        if desc and len(desc.strip()) >= 100:
            return FieldStatus(
                field_name='description',
                status='complete',
                value=desc[:100] + '...' if len(desc) > 100 else desc,
                score=max_score,
                max_score=max_score
            )

        if desc and len(desc.strip()) >= 30:
            return FieldStatus(
                field_name='description',
                status='partial',
                value=desc,
                score=max_score * 0.5,
                max_score=max_score,
                recommendation='Rozbuduj opis firmy. Dobry opis powinien mieć minimum 100-200 znaków i zawierać słowa kluczowe.'
            )

        return FieldStatus(
            field_name='description',
            status='missing',
            score=0,
            max_score=max_score,
            recommendation='Dodaj szczegółowy opis firmy. Opisz czym się zajmujesz, jakie usługi oferujesz i co Cię wyróżnia.'
        )

    def _check_services(self, company: Company) -> FieldStatus:
        """Check services list completeness"""
        max_score = FIELD_WEIGHTS['services']

        # Check company services relationship
        service_count = 0
        if hasattr(company, 'services') and company.services:
            service_count = len(company.services)

        # Also check services_offered text field
        has_services_text = bool(company.services_offered and len(company.services_offered.strip()) > 10)

        if service_count >= 3 or has_services_text:
            return FieldStatus(
                field_name='services',
                status='complete',
                value=service_count if service_count else 'W opisie',
                score=max_score,
                max_score=max_score
            )

        if service_count >= 1:
            return FieldStatus(
                field_name='services',
                status='partial',
                value=service_count,
                score=max_score * 0.5,
                max_score=max_score,
                recommendation='Dodaj więcej usług do wizytówki. Zalecane jest minimum 3-5 głównych usług.'
            )

        return FieldStatus(
            field_name='services',
            status='missing',
            score=0,
            max_score=max_score,
            recommendation='Dodaj listę usług lub produktów. Pomaga to klientom zrozumieć Twoją ofertę.'
        )

    def _check_reviews(self, company: Company, analysis: Optional[CompanyWebsiteAnalysis]) -> FieldStatus:
        """
        Check reviews presence and quality.

        Scoring logic (max 9 points):
        =============================
        COMPLETE (9/9 pts):
          - 5+ opinii AND ocena >= 4.0

        PARTIAL (3-8/9 pts):
          - Bazowo: 3 pkt za pierwszą opinię
          - +1 pkt za każdą kolejną opinię (do 4 opinii = 6 pkt max)
          - +1 pkt bonus jeśli ocena >= 4.0 (do 7 pkt max)

          Przykłady:
          - 1 opinia, ocena 3.5 → 3/9 pkt
          - 1 opinia, ocena 5.0 → 4/9 pkt (3 + 1 bonus)
          - 3 opinie, ocena 4.2 → 6/9 pkt (3 + 2 + 1 bonus)
          - 4 opinie, ocena 4.5 → 7/9 pkt (3 + 3 + 1 bonus)

        MISSING (0/9 pts):
          - Brak opinii
        """
        max_score = FIELD_WEIGHTS['reviews']

        review_count = 0
        rating = None

        if analysis:
            review_count = analysis.google_reviews_count or 0
            rating = analysis.google_rating

        # COMPLETE: 5+ reviews with good rating (4.0+) → full 9/9 points
        if review_count >= REVIEW_THRESHOLDS['good'] and rating and float(rating) >= 4.0:
            return FieldStatus(
                field_name='reviews',
                status='complete',
                value=f'{review_count} opinii, ocena {rating}',
                score=max_score,
                max_score=max_score,
                details={
                    'review_count': review_count,
                    'rating': float(rating),
                    'base_score': 3,
                    'additional_score': min(review_count - 1, 4),
                    'rating_bonus': 1,
                    'breakdown': f'3 pkt (1. opinia) + {min(review_count - 1, 4)} pkt (kolejne) + 1 pkt (ocena) = {max_score}/{max_score}'
                }
            )

        # PARTIAL: 1-4 reviews → proportional scoring
        if review_count >= REVIEW_THRESHOLDS['minimum']:
            # Base: 3 pts for first review + 1 pt per additional review (max 6 pts for 4 reviews)
            base_score = 3
            additional_score = min(review_count - 1, 4)
            partial_score = base_score + additional_score

            # Bonus: +1 pt for good rating (>= 4.0)
            rating_bonus = 0
            if rating and float(rating) >= 4.0:
                rating_bonus = 1
                partial_score = min(partial_score + rating_bonus, max_score - 2)  # max 7 pts

            # Build breakdown string
            breakdown_parts = [f'3 pkt (1. opinia)']
            if additional_score > 0:
                breakdown_parts.append(f'{additional_score} pkt (kolejne)')
            if rating_bonus > 0:
                breakdown_parts.append(f'1 pkt (ocena)')
            breakdown = ' + '.join(breakdown_parts) + f' = {partial_score}/{max_score}'

            return FieldStatus(
                field_name='reviews',
                status='partial',
                value=f'{review_count} opinii' + (f', ocena {rating}' if rating else ''),
                score=partial_score,
                max_score=max_score,
                recommendation='Zachęcaj klientów do zostawiania opinii. Więcej pozytywnych recenzji zwiększa zaufanie.',
                details={
                    'review_count': review_count,
                    'rating': float(rating) if rating else None,
                    'base_score': base_score,
                    'additional_score': additional_score,
                    'rating_bonus': rating_bonus,
                    'breakdown': breakdown
                }
            )

        # MISSING: no reviews → 0/9 points
        return FieldStatus(
            field_name='reviews',
            status='missing',
            value=review_count,
            score=0,
            max_score=max_score,
            recommendation='Zbieraj opinie od klientów. Wizytówki z opiniami są bardziej wiarygodne i lepiej widoczne.',
            details={
                'review_count': 0,
                'rating': None,
                'breakdown': '0 pkt (brak opinii)'
            }
        )

    def _get_priority(self, field_status: FieldStatus) -> str:
        """Determine recommendation priority based on field importance and status"""
        weight = FIELD_WEIGHTS.get(field_status.field_name, 0)

        if field_status.status == 'missing':
            if weight >= 10:
                return 'high'
            elif weight >= 8:
                return 'medium'
            else:
                return 'low'
        elif field_status.status == 'partial':
            if weight >= 10:
                return 'medium'
            else:
                return 'low'

        return 'low'

    # === AI-Powered Recommendations ===

    def generate_ai_recommendations(
        self,
        company: Company,
        result: AuditResult,
        user_id: Optional[int] = None
    ) -> List[Dict[str, Any]]:
        """
        Generate AI-powered recommendations using Gemini.

        Args:
            company: Company being audited
            result: AuditResult from the audit
            user_id: Optional user ID for cost tracking

        Returns:
            List of AI-generated recommendation dicts with keys:
            - priority: 'high', 'medium', 'low'
            - field: field name this applies to
            - recommendation: AI-generated recommendation text
            - action_steps: list of specific action steps
            - expected_impact: description of expected improvement
        """
        service = gemini_service.get_gemini_service()
        if not service:
            logger.warning("Gemini service not available - using static recommendations")
            return result.recommendations

        try:
            # Build context for AI
            prompt = self._build_ai_recommendation_prompt(company, result)

            # Call Gemini with cost tracking
            response_text = service.generate_text(
                prompt=prompt,
                feature='gbp_audit_ai',
                user_id=user_id,
                temperature=0.7,
                max_tokens=2000
            )

            # Parse AI response
            ai_recommendations = self._parse_ai_recommendations(response_text, result)

            logger.info(
                f"AI recommendations generated for company {company.id}: "
                f"{len(ai_recommendations)} recommendations"
            )

            return ai_recommendations

        except Exception as e:
            logger.error(f"AI recommendation generation failed: {e}")
            # Fall back to static recommendations
            return result.recommendations

    def _build_ai_recommendation_prompt(
        self,
        company: Company,
        result: AuditResult
    ) -> str:
        """
        Build prompt for Gemini to generate personalized recommendations.

        Args:
            company: Company being audited
            result: AuditResult with field statuses

        Returns:
            Formatted prompt string
        """
        # Build field status summary
        field_summary = []
        for field_name, field_status in result.fields.items():
            status_emoji = {
                'complete': '✅',
                'partial': '⚠️',
                'missing': '❌'
            }.get(field_status.status, '❓')

            field_summary.append(
                f"- {field_name}: {status_emoji} {field_status.status} "
                f"({field_status.score:.1f}/{field_status.max_score:.1f} pkt)"
            )

        # Get category info
        category_name = company.category.name if company.category else 'Nieznana'

        prompt = f"""Jesteś ekspertem od Google Business Profile (Wizytówki Google) i lokalnego SEO.

FIRMA: {company.name}
BRANŻA: {category_name}
MIASTO: {company.address_city or 'Nieznane'}
WYNIK AUDYTU: {result.completeness_score}/100

STATUS PÓL WIZYTÓWKI:
{chr(10).join(field_summary)}

LICZBA ZDJĘĆ: {result.photo_count}
LICZBA OPINII: {result.review_count}
OCENA: {result.average_rating or 'Brak'}

ZADANIE:
Wygeneruj 3-5 spersonalizowanych rekomendacji dla tej firmy, aby poprawić jej wizytówkę Google.

WYMAGANIA:
1. Każda rekomendacja powinna być konkretna i dostosowana do branży firmy
2. Skup się na polach z najniższymi wynikami
3. Podaj praktyczne kroki do wykonania
4. Używaj języka polskiego

ZWRÓĆ ODPOWIEDŹ W FORMACIE JSON (TYLKO JSON, BEZ MARKDOWN):
[
  {{
    "priority": "high|medium|low",
    "field": "nazwa_pola",
    "recommendation": "Krótki opis co poprawić",
    "action_steps": ["Krok 1", "Krok 2", "Krok 3"],
    "expected_impact": "Opis spodziewanej poprawy"
  }}
]

Priorytety:
- high: kluczowe pola (name, address, categories, description)
- medium: ważne pola (phone, website, photos, services)
- low: dodatkowe pola (hours, reviews)

Odpowiedź (TYLKO JSON):"""

        return prompt

    def _parse_ai_recommendations(
        self,
        response_text: str,
        fallback_result: AuditResult
    ) -> List[Dict[str, Any]]:
        """
        Parse AI response into structured recommendations.

        Args:
            response_text: Raw text from Gemini
            fallback_result: AuditResult to use for fallback

        Returns:
            List of recommendation dicts
        """
        try:
            # Clean up response - remove markdown code blocks if present
            cleaned = response_text.strip()
            if cleaned.startswith('```'):
                # Remove markdown code block markers
                lines = cleaned.split('\n')
                # Find JSON content between ``` markers
                json_lines = []
                in_json = False
                for line in lines:
                    if line.startswith('```') and not in_json:
                        in_json = True
                        continue
                    elif line.startswith('```') and in_json:
                        break
                    elif in_json:
                        json_lines.append(line)
                cleaned = '\n'.join(json_lines)

            # Parse JSON
            recommendations = json.loads(cleaned)

            # Validate and enhance recommendations
            valid_recommendations = []
            valid_priorities = {'high', 'medium', 'low'}
            valid_fields = set(FIELD_WEIGHTS.keys())

            for rec in recommendations:
                if not isinstance(rec, dict):
                    continue

                # Validate priority
                priority = rec.get('priority', 'medium')
                if priority not in valid_priorities:
                    priority = 'medium'

                # Validate field
                field = rec.get('field', 'general')
                if field not in valid_fields:
                    field = 'general'

                # Get impact score from field weights
                impact = FIELD_WEIGHTS.get(field, 5)

                valid_recommendations.append({
                    'priority': priority,
                    'field': field,
                    'recommendation': rec.get('recommendation', ''),
                    'action_steps': rec.get('action_steps', []),
                    'expected_impact': rec.get('expected_impact', ''),
                    'impact': impact,
                    'source': 'ai'
                })

            if valid_recommendations:
                # Sort by priority and impact
                priority_order = {'high': 0, 'medium': 1, 'low': 2}
                valid_recommendations.sort(
                    key=lambda x: (priority_order.get(x['priority'], 3), -x['impact'])
                )
                return valid_recommendations

        except json.JSONDecodeError as e:
            logger.warning(f"Failed to parse AI recommendations JSON: {e}")
        except Exception as e:
            logger.warning(f"Error processing AI recommendations: {e}")

        # Return fallback recommendations with source marker
        fallback = []
        for rec in fallback_result.recommendations:
            rec_copy = dict(rec)
            rec_copy['source'] = 'static'
            rec_copy['action_steps'] = []
            rec_copy['expected_impact'] = ''
            fallback.append(rec_copy)

        return fallback

    def audit_with_ai(
        self,
        company_id: int,
        user_id: Optional[int] = None
    ) -> AuditResult:
        """
        Run full GBP audit with AI-powered recommendations.

        Args:
            company_id: ID of the company to audit
            user_id: Optional user ID for cost tracking

        Returns:
            AuditResult with AI-enhanced recommendations
        """
        # Run standard audit
        result = self.audit_company(company_id)

        # Get company for AI context
        company = self.db.query(Company).filter(Company.id == company_id).first()
        if not company:
            return result

        # Generate AI recommendations
        ai_recommendations = self.generate_ai_recommendations(
            company=company,
            result=result,
            user_id=user_id
        )

        # Replace static recommendations with AI-generated ones
        result.recommendations = ai_recommendations

        return result


# === Convenience Functions ===

def audit_company(db: Session, company_id: int, save: bool = True) -> AuditResult:
    """
    Audit a company's GBP completeness.

    Args:
        db: Database session
        company_id: Company ID to audit
        save: Whether to save audit to database

    Returns:
        AuditResult with completeness score and recommendations
    """
    service = GBPAuditService(db)
    result = service.audit_company(company_id)

    if save:
        service.save_audit(result)

    return result


def get_company_audit(db: Session, company_id: int) -> Optional[GBPAudit]:
    """
    Get the latest audit for a company.

    Args:
        db: Database session
        company_id: Company ID

    Returns:
        Latest GBPAudit or None
    """
    service = GBPAuditService(db)
    return service.get_latest_audit(company_id)


def audit_company_with_ai(
    db: Session,
    company_id: int,
    save: bool = True,
    user_id: Optional[int] = None
) -> AuditResult:
    """
    Audit a company's GBP completeness with AI-powered recommendations.

    Args:
        db: Database session
        company_id: Company ID to audit
        save: Whether to save audit to database
        user_id: Optional user ID for cost tracking

    Returns:
        AuditResult with AI-enhanced recommendations
    """
    service = GBPAuditService(db)
    result = service.audit_with_ai(company_id, user_id=user_id)

    if save:
        service.save_audit(result, source='ai')

    return result


def batch_audit_companies(
    db: Session,
    company_ids: Optional[List[int]] = None,
    save: bool = True
) -> Dict[int, AuditResult]:
    """
    Audit multiple companies.

    Args:
        db: Database session
        company_ids: List of company IDs (None = all active companies)
        save: Whether to save audits to database

    Returns:
        Dict mapping company_id to AuditResult
    """
    service = GBPAuditService(db)

    # Get companies to audit
    if company_ids is None:
        companies = db.query(Company).filter(Company.status == 'active').all()
        company_ids = [c.id for c in companies]

    results = {}
    for company_id in company_ids:
        try:
            result = service.audit_company(company_id)
            if save:
                service.save_audit(result, source='automated')
            results[company_id] = result
        except Exception as e:
            logger.error(f"Failed to audit company {company_id}: {e}")

    return results


# === Google Places API Integration ===

def fetch_google_business_data(
    db: Session,
    company_id: int,
    force_refresh: bool = False
) -> Dict[str, Any]:
    """
    Fetch fresh Google Business Profile data from Google Places API.

    This function searches for the company on Google Places, retrieves
    detailed business information, and updates the CompanyWebsiteAnalysis record.

    Args:
        db: Database session
        company_id: Company ID to fetch data for
        force_refresh: If True, fetch even if recent data exists

    Returns:
        Dict with:
        - success: bool
        - steps: List of step results with status
        - data: Fetched Google data (if successful)
        - error: Error message (if failed)
    """
    import os
    import requests
    from datetime import datetime, timedelta

    result = {
        'success': False,
        'steps': [],
        'data': {},
        'error': None
    }

    # Get company
    company = db.query(Company).filter(Company.id == company_id).first()
    if not company:
        result['error'] = f'Firma o ID {company_id} nie znaleziona'
        return result

    # Check if we have recent data (less than 24 hours old)
    if not force_refresh:
        existing = db.query(CompanyWebsiteAnalysis).filter(
            CompanyWebsiteAnalysis.company_id == company_id
        ).order_by(CompanyWebsiteAnalysis.analyzed_at.desc()).first()

        if existing and existing.analyzed_at:
            age = datetime.now() - existing.analyzed_at
            if age < timedelta(hours=24) and existing.google_place_id:
                result['success'] = True
                result['steps'].append({
                    'step': 'cache_check',
                    'status': 'skipped',
                    'message': f'Dane pobrano {age.seconds // 3600}h temu - używam cache'
                })
                result['data'] = {
                    'google_place_id': existing.google_place_id,
                    'google_rating': float(existing.google_rating) if existing.google_rating else None,
                    'google_reviews_count': existing.google_reviews_count,
                    'google_photos_count': existing.google_photos_count,
                    'google_opening_hours': existing.google_opening_hours,
                    'cached': True
                }
                return result

    # Get API key
    api_key = os.getenv('GOOGLE_PLACES_API_KEY')
    if not api_key:
        result['error'] = 'Brak klucza API Google Places (GOOGLE_PLACES_API_KEY)'
        result['steps'].append({
            'step': 'api_key_check',
            'status': 'error',
            'message': result['error']
        })
        return result

    result['steps'].append({
        'step': 'api_key_check',
        'status': 'complete',
        'message': 'Klucz API skonfigurowany'
    })

    # Step 1: Search for place
    result['steps'].append({
        'step': 'find_place',
        'status': 'in_progress',
        'message': f'Szukam firmy "{company.name}" w Google Maps...'
    })

    city = company.address_city or 'Wejherowo'
    search_query = f'{company.name} {city}'

    try:
        find_response = requests.get(
            'https://maps.googleapis.com/maps/api/place/findplacefromtext/json',
            params={
                'input': search_query,
                'inputtype': 'textquery',
                'fields': 'place_id,name,formatted_address',
                'language': 'pl',
                'key': api_key,
            },
            timeout=15
        )
        find_response.raise_for_status()
        find_data = find_response.json()

        if find_data.get('status') != 'OK' or not find_data.get('candidates'):
            result['steps'][-1]['status'] = 'warning'
            result['steps'][-1]['message'] = f'Nie znaleziono firmy w Google Maps'
            result['error'] = 'Firma nie ma profilu Google Business lub nazwa jest inna niż w Google'
            return result

        candidate = find_data['candidates'][0]
        place_id = candidate.get('place_id')
        google_name = candidate.get('name')
        google_address = candidate.get('formatted_address')

        result['steps'][-1]['status'] = 'complete'
        result['steps'][-1]['message'] = f'Znaleziono: {google_name}'
        result['data']['google_place_id'] = place_id
        result['data']['google_name'] = google_name
        result['data']['google_address'] = google_address

    except requests.exceptions.Timeout:
        result['steps'][-1]['status'] = 'error'
        result['steps'][-1]['message'] = 'Timeout - Google API nie odpowiada'
        result['error'] = 'Timeout podczas wyszukiwania w Google Places API'
        return result
    except Exception as e:
        result['steps'][-1]['status'] = 'error'
        result['steps'][-1]['message'] = f'Błąd: {str(e)}'
        result['error'] = str(e)
        return result

    # Step 2: Get place details
    result['steps'].append({
        'step': 'get_details',
        'status': 'in_progress',
        'message': 'Pobieram szczegóły wizytówki...'
    })

    try:
        fields = [
            'name',
            'formatted_address',
            'formatted_phone_number',
            'website',
            'types',
            'url',
            'rating',
            'user_ratings_total',
            'opening_hours',
            'business_status',
            'photos',
        ]

        details_response = requests.get(
            'https://maps.googleapis.com/maps/api/place/details/json',
            params={
                'place_id': place_id,
                'fields': ','.join(fields),
                'language': 'pl',
                'key': api_key,
            },
            timeout=15
        )
        details_response.raise_for_status()
        details_data = details_response.json()

        if details_data.get('status') != 'OK':
            result['steps'][-1]['status'] = 'warning'
            result['steps'][-1]['message'] = f'Nie udało się pobrać szczegółów'
            result['error'] = f'Google Places API: {details_data.get("status")}'
            return result

        place = details_data.get('result', {})

        # Extract all data from Google
        google_name = place.get('name')
        google_address = place.get('formatted_address')
        phone = place.get('formatted_phone_number')
        website = place.get('website')
        types = place.get('types', [])
        maps_url = place.get('url')
        rating = place.get('rating')
        reviews_count = place.get('user_ratings_total')
        photos = place.get('photos', [])
        photos_count = len(photos) if photos else 0
        opening_hours = place.get('opening_hours', {})
        business_status = place.get('business_status')

        # Store all data in result
        result['data']['google_name'] = google_name
        result['data']['google_address'] = google_address
        result['data']['google_phone'] = phone
        result['data']['google_website'] = website
        result['data']['google_types'] = types
        result['data']['google_maps_url'] = maps_url
        result['data']['google_rating'] = rating
        result['data']['google_reviews_count'] = reviews_count
        result['data']['google_photos_count'] = photos_count
        result['data']['google_opening_hours'] = opening_hours
        result['data']['google_business_status'] = business_status
        result['data']['google_phone'] = phone
        result['data']['google_website'] = website

        result['steps'][-1]['status'] = 'complete'
        details_msg = []
        if rating:
            details_msg.append(f'Ocena: {rating}')
        if reviews_count:
            details_msg.append(f'{reviews_count} opinii')
        if photos_count:
            details_msg.append(f'{photos_count} zdjęć')
        result['steps'][-1]['message'] = ', '.join(details_msg) if details_msg else 'Pobrano dane'

    except requests.exceptions.Timeout:
        result['steps'][-1]['status'] = 'error'
        result['steps'][-1]['message'] = 'Timeout podczas pobierania szczegółów'
        result['error'] = 'Timeout podczas pobierania szczegółów z Google Places API'
        return result
    except Exception as e:
        result['steps'][-1]['status'] = 'error'
        result['steps'][-1]['message'] = f'Błąd: {str(e)}'
        result['error'] = str(e)
        return result

    # Step 3: Save to database
    result['steps'].append({
        'step': 'save_data',
        'status': 'in_progress',
        'message': 'Zapisuję dane w bazie...'
    })

    try:
        # Get or create CompanyWebsiteAnalysis record
        analysis = db.query(CompanyWebsiteAnalysis).filter(
            CompanyWebsiteAnalysis.company_id == company_id
        ).first()

        if not analysis:
            analysis = CompanyWebsiteAnalysis(
                company_id=company_id,
                url=company.website,
                analyzed_at=datetime.now()
            )
            db.add(analysis)

        # Update all Google fields
        analysis.google_place_id = place_id
        analysis.google_name = google_name
        analysis.google_address = google_address
        analysis.google_phone = phone
        analysis.google_website = website
        analysis.google_types = types if types else None
        analysis.google_maps_url = maps_url
        analysis.google_rating = rating
        analysis.google_reviews_count = reviews_count
        analysis.google_photos_count = photos_count
        analysis.google_opening_hours = opening_hours if opening_hours else None
        analysis.google_business_status = business_status
        analysis.analyzed_at = datetime.now()

        db.commit()

        result['steps'][-1]['status'] = 'complete'
        result['steps'][-1]['message'] = 'Dane zapisane pomyślnie'
        result['success'] = True

    except Exception as e:
        db.rollback()
        result['steps'][-1]['status'] = 'error'
        result['steps'][-1]['message'] = f'Błąd zapisu: {str(e)}'
        result['error'] = f'Błąd zapisu do bazy danych: {str(e)}'
        return result

    logger.info(
        f"Google data fetched for company {company_id}: "
        f"rating={rating}, reviews={reviews_count}, photos={photos_count}"
    )

    return result


# === Main for Testing ===

if __name__ == '__main__':
    import sys

    # Test the service
    logging.basicConfig(level=logging.INFO)

    # Check for --ai flag to test AI recommendations
    use_ai = '--ai' in sys.argv

    db = SessionLocal()
    try:
        # Get first active company
        company = db.query(Company).filter(Company.status == 'active').first()
        if company:
            print(f"\nAuditing company: {company.name} (ID: {company.id})")
            print("-" * 50)

            if use_ai:
                print("\n[AI MODE] Generating AI-powered recommendations...")
                result = audit_company_with_ai(db, company.id, save=False)
            else:
                result = audit_company(db, company.id, save=False)

            print(f"\nCompleteness Score: {result.completeness_score}/100")
            print(f"\nField Status:")
            for name, field in result.fields.items():
                status_icon = {'complete': '✅', 'partial': '⚠️', 'missing': '❌'}.get(field.status, '?')
                print(f"  {status_icon} {name}: {field.status} ({field.score:.1f}/{field.max_score:.1f})")

            print(f"\nRecommendations ({len(result.recommendations)}):")
            for rec in result.recommendations[:5]:
                source = rec.get('source', 'static')
                source_label = '[AI]' if source == 'ai' else '[STATIC]'
                print(f"\n  {source_label} [{rec['priority'].upper()}] {rec['field']}:")
                print(f"    {rec['recommendation']}")

                # Print AI-specific fields if present
                if rec.get('action_steps'):
                    print("    Action steps:")
                    for step in rec['action_steps']:
                        print(f"      • {step}")

                if rec.get('expected_impact'):
                    print(f"    Expected impact: {rec['expected_impact']}")
        else:
            print("No active companies found")

        print("\n" + "-" * 50)
        print("Usage: python gbp_audit_service.py [--ai]")
        print("  --ai  Generate AI-powered recommendations using Gemini")

    finally:
        db.close()
