"""
Norda Biznes - Database Models
===============================

SQLAlchemy models for PostgreSQL database.

Models:
- User: User accounts with authentication
- Company: Company information
- Category, Service, Competency: Company classifications
- AIChatConversation, AIChatMessage: Chat history
- AIAPICostLog: API cost tracking
- CompanyDigitalMaturity: Digital maturity scores and benchmarking
- CompanyWebsiteAnalysis: Website analysis and SEO metrics
- MaturityAssessment: Historical tracking of maturity scores
- GBPAudit: Google Business Profile audit results

Author: Norda Biznes Development Team
Created: 2025-11-23
Updated: 2026-01-08 (GBP Audit Tool)
"""

import os
import json
from datetime import datetime
from sqlalchemy import create_engine, Column, Integer, String, Text, Boolean, DateTime, ForeignKey, Table, Numeric, Date, Time, TypeDecorator, UniqueConstraint
from sqlalchemy.dialects.postgresql import ARRAY as PG_ARRAY, JSONB as PG_JSONB
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker, relationship
from flask_login import UserMixin

# Database configuration
DATABASE_URL = os.getenv(
    'DATABASE_URL',
    'postgresql://nordabiz_app:NordaBiz2025Secure@localhost:5432/nordabiz'
)

# Determine if we're using SQLite
IS_SQLITE = DATABASE_URL.startswith('sqlite')


class StringArray(TypeDecorator):
    """
    Platform-agnostic array type.
    Uses PostgreSQL ARRAY for PostgreSQL, stores as JSON string for SQLite.
    """
    impl = Text
    cache_ok = True

    def load_dialect_impl(self, dialect):
        if dialect.name == 'postgresql':
            return dialect.type_descriptor(PG_ARRAY(String))
        return dialect.type_descriptor(Text())

    def process_bind_param(self, value, dialect):
        if value is None:
            return None
        if dialect.name == 'postgresql':
            return value
        return json.dumps(value)

    def process_result_value(self, value, dialect):
        if value is None:
            return None
        if dialect.name == 'postgresql':
            return value
        if isinstance(value, list):
            return value
        return json.loads(value)


class JSONBType(TypeDecorator):
    """
    Platform-agnostic JSONB type.
    Uses PostgreSQL JSONB for PostgreSQL, stores as JSON string for SQLite.
    """
    impl = Text
    cache_ok = True

    def load_dialect_impl(self, dialect):
        if dialect.name == 'postgresql':
            return dialect.type_descriptor(PG_JSONB())
        return dialect.type_descriptor(Text())

    def process_bind_param(self, value, dialect):
        if value is None:
            return None
        if dialect.name == 'postgresql':
            return value
        return json.dumps(value)

    def process_result_value(self, value, dialect):
        if value is None:
            return None
        if dialect.name == 'postgresql':
            return value
        if isinstance(value, dict):
            return value
        return json.loads(value)


# Aliases for backwards compatibility
ARRAY = StringArray
JSONB = JSONBType


# Create engine
engine = create_engine(DATABASE_URL, echo=False)
SessionLocal = sessionmaker(bind=engine)
Base = declarative_base()


# ============================================================
# USER MANAGEMENT
# ============================================================

class User(Base, UserMixin):
    """User accounts"""
    __tablename__ = 'users'

    id = Column(Integer, primary_key=True)
    email = Column(String(255), unique=True, nullable=False, index=True)
    password_hash = Column(String(255), nullable=False)
    name = Column(String(255))
    company_nip = Column(String(10))
    company_id = Column(Integer, ForeignKey('companies.id'), nullable=True)
    phone = Column(String(50))

    # Status
    is_active = Column(Boolean, default=True)
    is_verified = Column(Boolean, default=False)
    is_admin = Column(Boolean, default=False)
    is_norda_member = Column(Boolean, default=False)

    # Timestamps
    created_at = Column(DateTime, default=datetime.now)
    last_login = Column(DateTime)
    verified_at = Column(DateTime)

    # Verification token
    verification_token = Column(String(255))
    verification_token_expires = Column(DateTime)

    # Password reset token
    reset_token = Column(String(255))
    reset_token_expires = Column(DateTime)

    # Relationships
    conversations = relationship('AIChatConversation', back_populates='user', cascade='all, delete-orphan')
    forum_topics = relationship('ForumTopic', back_populates='author', cascade='all, delete-orphan')
    forum_replies = relationship('ForumReply', back_populates='author', cascade='all, delete-orphan')

    def __repr__(self):
        return f'<User {self.email}>'


# ============================================================
# COMPANY DIRECTORY (existing schema from SQL)
# ============================================================

class Category(Base):
    """Company categories"""
    __tablename__ = 'categories'

    id = Column(Integer, primary_key=True)
    name = Column(String(100), nullable=False, unique=True)
    slug = Column(String(100), nullable=False, unique=True)
    description = Column(Text)
    icon = Column(String(50))
    sort_order = Column(Integer, default=0)
    created_at = Column(DateTime, default=datetime.now)

    companies = relationship('Company', back_populates='category')


class Company(Base):
    """Companies"""
    __tablename__ = 'companies'

    id = Column(Integer, primary_key=True)
    name = Column(String(255), nullable=False)
    legal_name = Column(String(255))
    slug = Column(String(255), nullable=False, unique=True, index=True)
    category_id = Column(Integer, ForeignKey('categories.id'))

    # Descriptions
    description_short = Column(Text)
    description_full = Column(Text)

    # Legal
    nip = Column(String(10), unique=True)
    regon = Column(String(14))
    krs = Column(String(10))

    # External registry slugs
    aleo_slug = Column(String(255))  # ALEO.com company slug for direct links

    # Contact
    website = Column(String(500))
    email = Column(String(255))
    phone = Column(String(50))

    # Address
    address_street = Column(String(255))
    address_city = Column(String(100))
    address_postal = Column(String(10))
    address_full = Column(Text)

    # Business data
    year_established = Column(Integer)
    employees_count = Column(Integer)
    capital_amount = Column(Numeric(15, 2))

    # Status (PostgreSQL uses ENUM types, no default here)
    status = Column(String(20))
    data_quality = Column(String(20))

    # Extended company info
    legal_form = Column(String(100))
    parent_organization = Column(String(255))
    industry_sector = Column(String(255))
    services_offered = Column(Text)
    operational_area = Column(String(500))
    languages_offered = Column(String(200))
    technologies_used = Column(Text)
    founding_history = Column(Text)  # Historia firmy + właściciele
    core_values = Column(Text)  # Wartości firmy
    branch_count = Column(Integer)
    employee_count_range = Column(String(50))

    # Data source tracking
    data_source = Column(String(100))
    data_quality_score = Column(Integer)
    last_verified_at = Column(DateTime)
    norda_biznes_url = Column(String(500))
    norda_biznes_member_id = Column(String(50))

    # Metadata
    last_updated = Column(DateTime, default=datetime.now)
    created_at = Column(DateTime, default=datetime.now)

    # === DIGITAL MATURITY (added 2025-11-26) ===
    digital_maturity_last_assessed = Column(DateTime)
    digital_maturity_score = Column(Integer)  # 0-100 composite score
    digital_maturity_rank_category = Column(Integer)
    digital_maturity_rank_overall = Column(Integer)

    # AI Readiness
    ai_enabled = Column(Boolean, default=False)
    ai_tools_used = Column(ARRAY(String))  # PostgreSQL array (will be Text for SQLite)
    data_structured = Column(Boolean, default=False)

    # IT Management
    it_manager_exists = Column(Boolean, default=False)
    it_outsourced = Column(Boolean, default=False)
    it_provider_company_id = Column(Integer, ForeignKey('companies.id'))

    # Website tracking
    website_last_analyzed = Column(DateTime)
    website_status = Column(String(20))  # 'active', 'broken', 'no_website'
    website_quality_score = Column(Integer)  # 0-100

    # Relationships
    category = relationship('Category', back_populates='companies')
    services = relationship('CompanyService', back_populates='company', cascade='all, delete-orphan')
    competencies = relationship('CompanyCompetency', back_populates='company', cascade='all, delete-orphan')
    certifications = relationship('Certification', back_populates='company', cascade='all, delete-orphan')
    awards = relationship('Award', back_populates='company', cascade='all, delete-orphan')
    events = relationship('CompanyEvent', back_populates='company', cascade='all, delete-orphan')

    # Digital Maturity relationships
    digital_maturity = relationship('CompanyDigitalMaturity', back_populates='company', uselist=False)
    website_analyses = relationship('CompanyWebsiteAnalysis', back_populates='company', cascade='all, delete-orphan')
    maturity_history = relationship('MaturityAssessment', back_populates='company', cascade='all, delete-orphan')

    # Quality tracking
    quality_tracking = relationship('CompanyQualityTracking', back_populates='company', uselist=False)

    # Website scraping and AI analysis
    website_content = relationship('CompanyWebsiteContent', back_populates='company', cascade='all, delete-orphan')
    ai_insights = relationship('CompanyAIInsights', back_populates='company', uselist=False)


class Service(Base):
    """Services offered by companies"""
    __tablename__ = 'services'

    id = Column(Integer, primary_key=True)
    name = Column(String(255), nullable=False, unique=True)
    slug = Column(String(255), nullable=False, unique=True)
    description = Column(Text)
    created_at = Column(DateTime, default=datetime.now)

    companies = relationship('CompanyService', back_populates='service')


class CompanyService(Base):
    """Many-to-many: Companies <-> Services"""
    __tablename__ = 'company_services'

    company_id = Column(Integer, ForeignKey('companies.id'), primary_key=True)
    service_id = Column(Integer, ForeignKey('services.id'), primary_key=True)
    is_primary = Column(Boolean, default=False)
    added_at = Column(DateTime, default=datetime.now)

    company = relationship('Company', back_populates='services')
    service = relationship('Service', back_populates='companies')


class Competency(Base):
    """Competencies/skills of companies"""
    __tablename__ = 'competencies'

    id = Column(Integer, primary_key=True)
    name = Column(String(255), nullable=False, unique=True)
    slug = Column(String(255), nullable=False, unique=True)
    category = Column(String(100))
    description = Column(Text)
    created_at = Column(DateTime, default=datetime.now)

    companies = relationship('CompanyCompetency', back_populates='competency')


class CompanyCompetency(Base):
    """Many-to-many: Companies <-> Competencies"""
    __tablename__ = 'company_competencies'

    company_id = Column(Integer, ForeignKey('companies.id'), primary_key=True)
    competency_id = Column(Integer, ForeignKey('competencies.id'), primary_key=True)
    level = Column(String(50))
    added_at = Column(DateTime, default=datetime.now)

    company = relationship('Company', back_populates='competencies')
    competency = relationship('Competency', back_populates='companies')


class Certification(Base):
    """Company certifications"""
    __tablename__ = 'certifications'

    id = Column(Integer, primary_key=True)
    company_id = Column(Integer, ForeignKey('companies.id'))
    name = Column(String(255), nullable=False)
    issuer = Column(String(255))
    certificate_number = Column(String(100))
    issue_date = Column(Date)
    expiry_date = Column(Date)
    is_active = Column(Boolean, default=True)
    created_at = Column(DateTime, default=datetime.now)

    company = relationship('Company', back_populates='certifications')


class Award(Base):
    """Company awards and achievements"""
    __tablename__ = 'awards'

    id = Column(Integer, primary_key=True)
    company_id = Column(Integer, ForeignKey('companies.id'))
    name = Column(String(255), nullable=False)
    issuer = Column(String(255))
    year = Column(Integer)
    description = Column(Text)
    created_at = Column(DateTime, default=datetime.now)

    company = relationship('Company', back_populates='awards')


class CompanyEvent(Base):
    """Company events and news"""
    __tablename__ = 'company_events'

    id = Column(Integer, primary_key=True)
    company_id = Column(Integer, ForeignKey('companies.id'))
    event_type = Column(String(50), nullable=False)
    title = Column(String(500), nullable=False)
    description = Column(Text)
    event_date = Column(Date)
    source_url = Column(String(1000))
    created_at = Column(DateTime, default=datetime.now)

    company = relationship('Company', back_populates='events')


# ============================================================
# DIGITAL MATURITY ASSESSMENT PLATFORM
# ============================================================

class CompanyDigitalMaturity(Base):
    """Central dashboard for company digital maturity - composite scores and benchmarking"""
    __tablename__ = 'company_digital_maturity'

    id = Column(Integer, primary_key=True)
    company_id = Column(Integer, ForeignKey('companies.id'), nullable=False, unique=True, index=True)
    last_updated = Column(DateTime, default=datetime.now)

    # === COMPOSITE SCORES (0-100 each) ===
    overall_score = Column(Integer)
    online_presence_score = Column(Integer)
    social_media_score = Column(Integer)
    it_infrastructure_score = Column(Integer)
    business_applications_score = Column(Integer)
    backup_disaster_recovery_score = Column(Integer)
    cybersecurity_score = Column(Integer)
    ai_readiness_score = Column(Integer)
    digital_marketing_score = Column(Integer)

    # === GAPS & OPPORTUNITIES ===
    critical_gaps = Column(ARRAY(String))  # ['no_backup', 'no_firewall', etc.]
    improvement_priority = Column(String(20))  # 'critical', 'high', 'medium', 'low'
    estimated_investment_needed = Column(Numeric(10, 2))  # PLN

    # === BENCHMARKING ===
    rank_in_category = Column(Integer)  # position in category
    rank_overall = Column(Integer)  # overall position
    percentile = Column(Integer)  # top X% of companies

    # === SALES INTELLIGENCE ===
    total_opportunity_value = Column(Numeric(10, 2))  # potential sales value (PLN)
    sales_readiness = Column(String(20))  # 'hot', 'warm', 'cold', 'not_ready'

    # Relationship
    company = relationship('Company', back_populates='digital_maturity')


class CompanyWebsiteAnalysis(Base):
    """Detailed website and online presence analysis"""
    __tablename__ = 'company_website_analysis'

    id = Column(Integer, primary_key=True)
    company_id = Column(Integer, ForeignKey('companies.id'), nullable=False, index=True)
    analyzed_at = Column(DateTime, default=datetime.now, index=True)

    # === BASIC INFO ===
    website_url = Column(String(500))
    final_url = Column(String(500))  # After redirects
    http_status_code = Column(Integer)
    load_time_ms = Column(Integer)

    # === TECHNICAL ===
    has_ssl = Column(Boolean, default=False)
    ssl_expires_at = Column(Date)
    ssl_issuer = Column(String(100))  # Certificate Authority (Let's Encrypt, DigiCert, etc.)
    is_responsive = Column(Boolean, default=False)  # mobile-friendly
    cms_detected = Column(String(100))
    frameworks_detected = Column(ARRAY(String))  # ['WordPress', 'Bootstrap', etc.]

    # === HOSTING & SERVER (from audit) ===
    last_modified_at = Column(DateTime)
    hosting_provider = Column(String(100))
    hosting_ip = Column(String(45))
    server_software = Column(String(100))
    site_author = Column(String(255))  # Website creator/agency
    site_generator = Column(String(100))
    domain_registrar = Column(String(100))
    is_mobile_friendly = Column(Boolean, default=False)
    has_viewport_meta = Column(Boolean, default=False)

    # === GOOGLE BUSINESS (from audit) ===
    google_rating = Column(Numeric(2, 1))
    google_reviews_count = Column(Integer)
    google_place_id = Column(String(100))
    google_business_status = Column(String(50))
    google_opening_hours = Column(JSONB)  # Opening hours from GBP
    google_photos_count = Column(Integer)  # Number of photos on GBP

    # === AUDIT METADATA ===
    audit_source = Column(String(50), default='automated')
    audit_version = Column(String(20), default='1.0')
    audit_errors = Column(Text)

    # === CONTENT RICHNESS ===
    content_richness_score = Column(Integer)  # 1-10
    page_count_estimate = Column(Integer)
    word_count_homepage = Column(Integer)
    has_blog = Column(Boolean, default=False)
    has_portfolio = Column(Boolean, default=False)
    has_contact_form = Column(Boolean, default=False)
    has_live_chat = Column(Boolean, default=False)

    # === EXTRACTED CONTENT ===
    content_summary = Column(Text)  # AI-generated summary from website
    services_extracted = Column(ARRAY(String))  # Services mentioned on website
    main_keywords = Column(ARRAY(String))  # Top keywords

    # === SEO ===
    seo_title = Column(String(500))
    seo_description = Column(Text)
    has_sitemap = Column(Boolean, default=False)
    has_robots_txt = Column(Boolean, default=False)
    google_indexed_pages = Column(Integer)

    # === PAGESPEED INSIGHTS SCORES (0-100) ===
    pagespeed_seo_score = Column(Integer)  # Google PageSpeed SEO score 0-100
    pagespeed_performance_score = Column(Integer)  # Google PageSpeed Performance score 0-100
    pagespeed_accessibility_score = Column(Integer)  # Google PageSpeed Accessibility score 0-100
    pagespeed_best_practices_score = Column(Integer)  # Google PageSpeed Best Practices score 0-100
    pagespeed_audits = Column(JSONB)  # Full PageSpeed audit results as JSON

    # === ON-PAGE SEO DETAILS ===
    meta_title = Column(String(500))  # Full meta title from <title> tag
    meta_description = Column(Text)  # Full meta description from <meta name="description">
    meta_keywords = Column(Text)  # Meta keywords (legacy, rarely used)

    # Heading structure
    h1_count = Column(Integer)  # Number of H1 tags on homepage (should be 1)
    h2_count = Column(Integer)  # Number of H2 tags on homepage
    h3_count = Column(Integer)  # Number of H3 tags on homepage
    h1_text = Column(String(500))  # Text content of first H1 tag

    # Image analysis
    total_images = Column(Integer)  # Total number of images
    images_without_alt = Column(Integer)  # Images missing alt attribute - accessibility issue
    images_with_alt = Column(Integer)  # Images with proper alt text

    # Link analysis
    internal_links_count = Column(Integer)  # Links to same domain
    external_links_count = Column(Integer)  # Links to external domains
    broken_links_count = Column(Integer)  # Links returning 4xx/5xx

    # Structured data (Schema.org, JSON-LD, Microdata)
    has_structured_data = Column(Boolean, default=False)  # Whether page contains JSON-LD, Microdata, or RDFa
    structured_data_types = Column(ARRAY(String))  # Schema.org types found: Organization, LocalBusiness, etc.
    structured_data_json = Column(JSONB)  # Full structured data as JSON

    # === TECHNICAL SEO ===
    # Canonical URL handling
    has_canonical = Column(Boolean, default=False)  # Whether page has canonical URL defined
    canonical_url = Column(String(500))  # The canonical URL value

    # Indexability
    is_indexable = Column(Boolean, default=True)  # Whether page can be indexed (no noindex directive)
    noindex_reason = Column(String(200))  # Reason if page is not indexable: meta tag, robots.txt, etc.

    # Core Web Vitals
    viewport_configured = Column(Boolean)  # Whether viewport meta tag is properly configured
    largest_contentful_paint_ms = Column(Integer)  # Core Web Vital: LCP in milliseconds
    first_input_delay_ms = Column(Integer)  # Core Web Vital: FID in milliseconds
    cumulative_layout_shift = Column(Numeric(5, 3))  # Core Web Vital: CLS score

    # Open Graph & Social Meta
    has_og_tags = Column(Boolean, default=False)  # Whether page has Open Graph tags
    og_title = Column(String(500))  # Open Graph title
    og_description = Column(Text)  # Open Graph description
    og_image = Column(String(500))  # Open Graph image URL
    has_twitter_cards = Column(Boolean, default=False)  # Whether page has Twitter Card meta tags

    # Language & International
    html_lang = Column(String(10))  # Language attribute from <html lang="...">
    has_hreflang = Column(Boolean, default=False)  # Whether page has hreflang tags

    # === SEO AUDIT METADATA ===
    seo_audit_version = Column(String(20))  # Version of SEO audit script used
    seo_audited_at = Column(DateTime)  # Timestamp of last SEO audit
    seo_audit_errors = Column(ARRAY(String))  # Errors encountered during SEO audit
    seo_overall_score = Column(Integer)  # Calculated overall SEO score 0-100
    seo_health_score = Column(Integer)  # On-page SEO health score 0-100
    seo_issues = Column(JSONB)  # List of SEO issues found with severity levels

    # === DOMAIN ===
    domain_registered_at = Column(Date)
    domain_expires_at = Column(Date)
    domain_age_years = Column(Integer)

    # === ANALYTICS ===
    has_google_analytics = Column(Boolean, default=False)
    has_google_tag_manager = Column(Boolean, default=False)
    has_facebook_pixel = Column(Boolean, default=False)

    # === OPPORTUNITY SCORING ===
    needs_redesign = Column(Boolean, default=False)
    missing_features = Column(ARRAY(String))  # ['blog', 'portfolio', 'ssl', etc.]
    opportunity_score = Column(Integer)  # 0-100
    estimated_project_value = Column(Numeric(10, 2))  # PLN
    opportunity_notes = Column(Text)

    # Relationship
    company = relationship('Company', back_populates='website_analyses')


class CompanyQualityTracking(Base):
    """Quality tracking for company data - verification counter and quality score"""
    __tablename__ = 'company_quality_tracking'

    id = Column(Integer, primary_key=True)
    company_id = Column(Integer, ForeignKey('companies.id'), nullable=False, unique=True, index=True)
    verification_count = Column(Integer, default=0)
    last_verified_at = Column(DateTime)
    verified_by = Column(String(100))
    verification_notes = Column(Text)
    quality_score = Column(Integer)  # 0-100%
    issues_found = Column(Integer, default=0)
    issues_fixed = Column(Integer, default=0)
    created_at = Column(DateTime, default=datetime.utcnow)
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)

    # Relationship
    company = relationship('Company', back_populates='quality_tracking')


class CompanyWebsiteContent(Base):
    """Scraped website content for companies"""
    __tablename__ = 'company_website_content'

    id = Column(Integer, primary_key=True)
    company_id = Column(Integer, ForeignKey('companies.id'), nullable=False, index=True)
    scraped_at = Column(DateTime, default=datetime.utcnow)
    url = Column(String(500))
    http_status = Column(Integer)
    raw_html = Column(Text)
    raw_text = Column(Text)
    page_title = Column(String(500))
    meta_description = Column(Text)
    main_content = Column(Text)
    email_addresses = Column(ARRAY(String))
    phone_numbers = Column(ARRAY(String))
    social_media = Column(JSONB)
    word_count = Column(Integer)

    # Relationship
    company = relationship('Company', back_populates='website_content')


class CompanyAIInsights(Base):
    """AI-generated insights from website analysis"""
    __tablename__ = 'company_ai_insights'

    id = Column(Integer, primary_key=True)
    company_id = Column(Integer, ForeignKey('companies.id'), nullable=False, unique=True, index=True)
    content_id = Column(Integer, ForeignKey('company_website_content.id'))
    business_summary = Column(Text)
    services_list = Column(ARRAY(String))
    target_market = Column(Text)
    unique_selling_points = Column(ARRAY(String))
    company_values = Column(ARRAY(String))
    certifications = Column(ARRAY(String))
    suggested_category = Column(String(100))
    category_confidence = Column(Numeric(3, 2))
    industry_tags = Column(ARRAY(String))
    ai_confidence_score = Column(Numeric(3, 2))
    processing_time_ms = Column(Integer)
    analyzed_at = Column(DateTime, default=datetime.utcnow)

    # Relationship
    company = relationship('Company', back_populates='ai_insights')


class MaturityAssessment(Base):
    """Historical tracking of digital maturity scores over time"""
    __tablename__ = 'maturity_assessments'

    id = Column(Integer, primary_key=True)
    company_id = Column(Integer, ForeignKey('companies.id'), nullable=False, index=True)
    assessed_at = Column(DateTime, default=datetime.now, index=True)
    assessed_by_user_id = Column(Integer, ForeignKey('users.id'))
    assessment_type = Column(String(50))  # 'full', 'quick', 'self_reported', 'audit'

    # === SNAPSHOT OF SCORES ===
    overall_score = Column(Integer)
    online_presence_score = Column(Integer)
    social_media_score = Column(Integer)
    it_infrastructure_score = Column(Integer)
    business_applications_score = Column(Integer)
    backup_dr_score = Column(Integer)
    cybersecurity_score = Column(Integer)
    ai_readiness_score = Column(Integer)

    # === CHANGES SINCE LAST ASSESSMENT ===
    score_change = Column(Integer)  # +5, -3, etc.
    areas_improved = Column(ARRAY(String))  # ['cybersecurity', 'backup']
    areas_declined = Column(ARRAY(String))  # ['social_media']

    notes = Column(Text)

    # Relationship
    company = relationship('Company', back_populates='maturity_history')


# ============================================================
# AI CHAT
# ============================================================

class AIChatConversation(Base):
    """Chat conversations"""
    __tablename__ = 'ai_chat_conversations'

    id = Column(Integer, primary_key=True)
    user_id = Column(Integer, ForeignKey('users.id'), nullable=False, index=True)
    title = Column(String(255))
    conversation_type = Column(String(50), default='general')

    # Timestamps
    started_at = Column(DateTime, default=datetime.now)
    updated_at = Column(DateTime, default=datetime.now, onupdate=datetime.now)
    is_active = Column(Boolean, default=True)

    # Metrics
    message_count = Column(Integer, default=0)
    model_name = Column(String(100))

    # Relationships
    user = relationship('User', back_populates='conversations')
    messages = relationship('AIChatMessage', back_populates='conversation', cascade='all, delete-orphan', order_by='AIChatMessage.created_at')


class AIChatMessage(Base):
    """Chat messages"""
    __tablename__ = 'ai_chat_messages'

    id = Column(Integer, primary_key=True)
    conversation_id = Column(Integer, ForeignKey('ai_chat_conversations.id'), nullable=False, index=True)
    created_at = Column(DateTime, default=datetime.now)

    # Message
    role = Column(String(20), nullable=False)  # 'user' or 'assistant'
    content = Column(Text, nullable=False)

    # Metrics
    tokens_input = Column(Integer)
    tokens_output = Column(Integer)
    cost_usd = Column(Numeric(10, 6))
    latency_ms = Column(Integer)

    # Flags
    edited = Column(Boolean, default=False)
    regenerated = Column(Boolean, default=False)

    # Feedback (for assistant messages)
    feedback_rating = Column(Integer)  # 1 = thumbs down, 2 = thumbs up
    feedback_comment = Column(Text)  # Optional user comment
    feedback_at = Column(DateTime)

    # Quality metrics (for analytics)
    companies_mentioned = Column(Integer)  # Number of companies in response
    query_intent = Column(String(100))  # Detected intent: 'find_company', 'get_info', 'compare', etc.

    # Relationship
    conversation = relationship('AIChatConversation', back_populates='messages')
    feedback = relationship('AIChatFeedback', back_populates='message', uselist=False)


class AIChatFeedback(Base):
    """Detailed feedback for AI responses - for learning and improvement"""
    __tablename__ = 'ai_chat_feedback'

    id = Column(Integer, primary_key=True)
    message_id = Column(Integer, ForeignKey('ai_chat_messages.id'), nullable=False, unique=True)
    user_id = Column(Integer, ForeignKey('users.id'), nullable=False)
    created_at = Column(DateTime, default=datetime.now)

    # Rating
    rating = Column(Integer, nullable=False)  # 1-5 stars or 1=bad, 2=good
    is_helpful = Column(Boolean)  # Was the answer helpful?
    is_accurate = Column(Boolean)  # Was the information accurate?
    found_company = Column(Boolean)  # Did user find what they were looking for?

    # Feedback text
    comment = Column(Text)
    suggested_answer = Column(Text)  # What should have been the answer?

    # Context for learning
    original_query = Column(Text)  # The user's question
    expected_companies = Column(Text)  # JSON list of company names user expected

    # Relationship
    message = relationship('AIChatMessage', back_populates='feedback')


# ============================================================
# FORUM
# ============================================================

class ForumTopic(Base):
    """Forum topics/threads"""
    __tablename__ = 'forum_topics'

    id = Column(Integer, primary_key=True)
    title = Column(String(255), nullable=False)
    content = Column(Text, nullable=False)
    author_id = Column(Integer, ForeignKey('users.id'), nullable=False)

    # Status
    is_pinned = Column(Boolean, default=False)
    is_locked = Column(Boolean, default=False)
    views_count = Column(Integer, default=0)

    # Timestamps
    created_at = Column(DateTime, default=datetime.now)
    updated_at = Column(DateTime, default=datetime.now, onupdate=datetime.now)

    # Relationships
    author = relationship('User', back_populates='forum_topics')
    replies = relationship('ForumReply', back_populates='topic', cascade='all, delete-orphan', order_by='ForumReply.created_at')

    @property
    def reply_count(self):
        return len(self.replies)

    @property
    def last_activity(self):
        if self.replies:
            return max(r.created_at for r in self.replies)
        return self.created_at


class ForumReply(Base):
    """Forum replies to topics"""
    __tablename__ = 'forum_replies'

    id = Column(Integer, primary_key=True)
    topic_id = Column(Integer, ForeignKey('forum_topics.id'), nullable=False)
    author_id = Column(Integer, ForeignKey('users.id'), nullable=False)
    content = Column(Text, nullable=False)

    # Timestamps
    created_at = Column(DateTime, default=datetime.now)
    updated_at = Column(DateTime, default=datetime.now, onupdate=datetime.now)

    # Relationships
    topic = relationship('ForumTopic', back_populates='replies')
    author = relationship('User', back_populates='forum_replies')


class AIAPICostLog(Base):
    """API cost tracking"""
    __tablename__ = 'ai_api_costs'

    id = Column(Integer, primary_key=True)
    timestamp = Column(DateTime, default=datetime.now, index=True)

    # API details
    api_provider = Column(String(50))  # 'gemini'
    model_name = Column(String(100))
    feature = Column(String(100))  # 'ai_chat', 'general', etc.

    # User context
    user_id = Column(Integer, ForeignKey('users.id'), index=True)

    # Token usage
    input_tokens = Column(Integer)
    output_tokens = Column(Integer)
    total_tokens = Column(Integer)

    # Costs
    input_cost = Column(Numeric(10, 6))
    output_cost = Column(Numeric(10, 6))
    total_cost = Column(Numeric(10, 6))

    # Status
    success = Column(Boolean, default=True)
    error_message = Column(Text)
    latency_ms = Column(Integer)

    # Privacy
    prompt_hash = Column(String(64))  # SHA256 hash, not storing actual prompts


# ============================================================
# CALENDAR / EVENTS
# ============================================================

class NordaEvent(Base):
    """Spotkania i wydarzenia Norda Biznes"""
    __tablename__ = 'norda_events'

    id = Column(Integer, primary_key=True)
    title = Column(String(255), nullable=False)
    description = Column(Text)
    event_type = Column(String(50), default='meeting')  # meeting, webinar, networking, other

    # Data i czas
    event_date = Column(Date, nullable=False)
    time_start = Column(Time)
    time_end = Column(Time)

    # Lokalizacja
    location = Column(String(500))  # Adres lub "Online"
    location_url = Column(String(1000))  # Link do Google Maps lub Zoom

    # Prelegent (opcjonalnie)
    speaker_name = Column(String(255))
    speaker_company_id = Column(Integer, ForeignKey('companies.id'))

    # Metadane
    is_featured = Column(Boolean, default=False)
    max_attendees = Column(Integer)
    created_by = Column(Integer, ForeignKey('users.id'))
    created_at = Column(DateTime, default=datetime.now)

    # Relationships
    speaker_company = relationship('Company')
    creator = relationship('User', foreign_keys=[created_by])
    attendees = relationship('EventAttendee', back_populates='event', cascade='all, delete-orphan')

    @property
    def attendee_count(self):
        return len(self.attendees)

    @property
    def is_past(self):
        from datetime import date
        return self.event_date < date.today()


class EventAttendee(Base):
    """RSVP na wydarzenia"""
    __tablename__ = 'event_attendees'

    id = Column(Integer, primary_key=True)
    event_id = Column(Integer, ForeignKey('norda_events.id'), nullable=False)
    user_id = Column(Integer, ForeignKey('users.id'), nullable=False)
    status = Column(String(20), default='confirmed')  # confirmed, maybe, declined
    registered_at = Column(DateTime, default=datetime.now)

    event = relationship('NordaEvent', back_populates='attendees')
    user = relationship('User')


# ============================================================
# PRIVATE MESSAGES
# ============================================================

class PrivateMessage(Base):
    """Wiadomości prywatne między członkami"""
    __tablename__ = 'private_messages'

    id = Column(Integer, primary_key=True)
    sender_id = Column(Integer, ForeignKey('users.id'), nullable=False)
    recipient_id = Column(Integer, ForeignKey('users.id'), nullable=False)

    subject = Column(String(255))
    content = Column(Text, nullable=False)

    is_read = Column(Boolean, default=False)
    read_at = Column(DateTime)

    # Dla wątków konwersacji
    parent_id = Column(Integer, ForeignKey('private_messages.id'))

    created_at = Column(DateTime, default=datetime.now)

    sender = relationship('User', foreign_keys=[sender_id], backref='sent_messages')
    recipient = relationship('User', foreign_keys=[recipient_id], backref='received_messages')
    parent = relationship('PrivateMessage', remote_side=[id])


# ============================================================
# B2B CLASSIFIEDS
# ============================================================

class Classified(Base):
    """Ogłoszenia B2B - Szukam/Oferuję"""
    __tablename__ = 'classifieds'

    id = Column(Integer, primary_key=True)
    author_id = Column(Integer, ForeignKey('users.id'), nullable=False)
    company_id = Column(Integer, ForeignKey('companies.id'))

    # Typ ogłoszenia
    listing_type = Column(String(20), nullable=False)  # 'szukam', 'oferuje'
    category = Column(String(50), nullable=False)  # uslugi, produkty, wspolpraca, praca, inne

    title = Column(String(255), nullable=False)
    description = Column(Text, nullable=False)

    # Opcjonalne szczegóły
    budget_info = Column(String(255))  # "do negocjacji", "5000-10000 PLN"
    location_info = Column(String(255))  # Wejherowo, Cała Polska, Online

    # Status
    is_active = Column(Boolean, default=True)
    expires_at = Column(DateTime)  # Auto-wygaśnięcie po 30 dniach
    views_count = Column(Integer, default=0)

    created_at = Column(DateTime, default=datetime.now)
    updated_at = Column(DateTime, default=datetime.now, onupdate=datetime.now)

    author = relationship('User', backref='classifieds')
    company = relationship('Company')

    @property
    def is_expired(self):
        if self.expires_at:
            return datetime.now() > self.expires_at
        return False


class CompanyContact(Base):
    """Multiple contacts (phones, emails) per company with source tracking"""
    __tablename__ = 'company_contacts'

    id = Column(Integer, primary_key=True)
    company_id = Column(Integer, ForeignKey('companies.id', ondelete='CASCADE'), nullable=False, index=True)

    # Contact type: 'phone', 'email', 'fax', 'mobile'
    contact_type = Column(String(20), nullable=False, index=True)

    # Contact value (phone number or email address)
    value = Column(String(255), nullable=False)

    # Purpose/description: 'Biuro', 'Sprzedaż', 'Właściciel', 'Transport', 'Serwis', etc.
    purpose = Column(String(100))

    # Is this the primary contact of this type?
    is_primary = Column(Boolean, default=False)

    # Source of this contact data
    source = Column(String(100))  # 'website', 'krs', 'google_business', 'facebook', 'manual', 'brave_search'
    source_url = Column(String(500))  # URL where the contact was found
    source_date = Column(Date)  # When the contact was found/verified

    # Validation
    is_verified = Column(Boolean, default=False)
    verified_at = Column(DateTime)
    verified_by = Column(String(100))

    # Metadata
    created_at = Column(DateTime, default=datetime.now)
    updated_at = Column(DateTime, default=datetime.now, onupdate=datetime.now)

    # Relationship
    company = relationship('Company', backref='contacts')

    __table_args__ = (
        UniqueConstraint('company_id', 'contact_type', 'value', name='uq_company_contact_type_value'),
    )


class CompanySocialMedia(Base):
    """Social media profiles for companies with verification tracking"""
    __tablename__ = 'company_social_media'

    id = Column(Integer, primary_key=True)
    company_id = Column(Integer, ForeignKey('companies.id', ondelete='CASCADE'), nullable=False, index=True)
    platform = Column(String(50), nullable=False, index=True)  # facebook, linkedin, instagram, youtube, twitter
    url = Column(String(500), nullable=False)

    # Tracking freshness
    verified_at = Column(DateTime, nullable=False, default=datetime.now, index=True)
    source = Column(String(100))  # website_scrape, brave_search, manual, facebook_api

    # Validation
    is_valid = Column(Boolean, default=True)
    last_checked_at = Column(DateTime)
    check_status = Column(String(50))  # ok, 404, redirect, blocked

    # Metadata from platform
    page_name = Column(String(255))
    followers_count = Column(Integer)

    created_at = Column(DateTime, default=datetime.now)
    updated_at = Column(DateTime, default=datetime.now, onupdate=datetime.now)

    # Relationship
    company = relationship('Company', backref='social_media_profiles')

    __table_args__ = (
        UniqueConstraint('company_id', 'platform', 'url', name='uq_company_platform_url'),
    )


class CompanyRecommendation(Base):
    """Peer recommendations between NORDA BIZNES members"""
    __tablename__ = 'company_recommendations'

    id = Column(Integer, primary_key=True)
    company_id = Column(Integer, ForeignKey('companies.id', ondelete='CASCADE'), nullable=False, index=True)
    user_id = Column(Integer, ForeignKey('users.id', ondelete='CASCADE'), nullable=False, index=True)

    # Recommendation content
    recommendation_text = Column(Text, nullable=False)
    service_category = Column(String(200))  # Optional: specific service recommended for

    # Privacy settings
    show_contact = Column(Boolean, default=True)  # Show recommender's contact info

    # Moderation
    status = Column(String(20), default='pending', index=True)  # pending, approved, rejected
    moderated_by = Column(Integer, ForeignKey('users.id'), nullable=True)
    moderated_at = Column(DateTime)
    rejection_reason = Column(Text)

    # Timestamps
    created_at = Column(DateTime, default=datetime.now)
    updated_at = Column(DateTime, default=datetime.now, onupdate=datetime.now)

    # Relationships
    company = relationship('Company', backref='recommendations')
    user = relationship('User', foreign_keys=[user_id], backref='recommendations_given')
    moderator = relationship('User', foreign_keys=[moderated_by], backref='recommendations_moderated')

    __table_args__ = (
        UniqueConstraint('user_id', 'company_id', name='uq_user_company_recommendation'),
    )


class UserNotification(Base):
    """
    In-app notifications for users.
    Supports badges and notification center.
    """
    __tablename__ = 'user_notifications'

    id = Column(Integer, primary_key=True)
    user_id = Column(Integer, ForeignKey('users.id', ondelete='CASCADE'), nullable=False, index=True)

    # Notification content
    title = Column(String(255), nullable=False)
    message = Column(Text)
    notification_type = Column(String(50), default='info', index=True)
    # Types: news, system, message, event, alert

    # Related entity (optional)
    related_type = Column(String(50))  # company_news, event, message
    related_id = Column(Integer)

    # Status
    is_read = Column(Boolean, default=False, index=True)
    read_at = Column(DateTime)

    # Link
    action_url = Column(String(500))

    # Timestamps
    created_at = Column(DateTime, default=datetime.now, index=True)

    # Relationship
    user = relationship('User', backref='notifications')

    def mark_as_read(self):
        self.is_read = True
        self.read_at = datetime.now()


# ============================================================
# GOOGLE BUSINESS PROFILE AUDIT
# ============================================================

class GBPAudit(Base):
    """
    Google Business Profile audit results for companies.
    Tracks completeness scores and provides improvement recommendations.
    """
    __tablename__ = 'gbp_audits'

    id = Column(Integer, primary_key=True)
    company_id = Column(Integer, ForeignKey('companies.id', ondelete='CASCADE'), nullable=False, index=True)

    # Audit timestamp
    audit_date = Column(DateTime, default=datetime.now, nullable=False, index=True)

    # Completeness scoring (0-100)
    completeness_score = Column(Integer)

    # Field-by-field status tracking
    # Example: {"name": {"status": "complete", "value": "Company Name"}, "phone": {"status": "missing"}, ...}
    fields_status = Column(JSONB)

    # AI-generated recommendations
    # Example: [{"priority": "high", "field": "description", "recommendation": "Add a detailed business description..."}, ...]
    recommendations = Column(JSONB)

    # Individual field scores (for detailed breakdown)
    has_name = Column(Boolean, default=False)
    has_address = Column(Boolean, default=False)
    has_phone = Column(Boolean, default=False)
    has_website = Column(Boolean, default=False)
    has_hours = Column(Boolean, default=False)
    has_categories = Column(Boolean, default=False)
    has_photos = Column(Boolean, default=False)
    has_description = Column(Boolean, default=False)
    has_services = Column(Boolean, default=False)
    has_reviews = Column(Boolean, default=False)

    # Photo counts
    photo_count = Column(Integer, default=0)
    logo_present = Column(Boolean, default=False)
    cover_photo_present = Column(Boolean, default=False)

    # Review metrics
    review_count = Column(Integer, default=0)
    average_rating = Column(Numeric(2, 1))

    # Google Place data
    google_place_id = Column(String(100))
    google_maps_url = Column(String(500))

    # Audit metadata
    audit_source = Column(String(50), default='manual')  # manual, automated, api
    audit_version = Column(String(20), default='1.0')
    audit_errors = Column(Text)

    # Timestamps
    created_at = Column(DateTime, default=datetime.now)
    updated_at = Column(DateTime, default=datetime.now, onupdate=datetime.now)

    # Relationship
    company = relationship('Company', backref='gbp_audits')

    def __repr__(self):
        return f'<GBPAudit company_id={self.company_id} score={self.completeness_score}>'

    @property
    def score_category(self):
        """Return score category: excellent, good, needs_work, poor"""
        if self.completeness_score is None:
            return 'unknown'
        if self.completeness_score >= 90:
            return 'excellent'
        elif self.completeness_score >= 70:
            return 'good'
        elif self.completeness_score >= 50:
            return 'needs_work'
        else:
            return 'poor'


# ============================================================
# MEMBERSHIP FEES
# ============================================================

class MembershipFee(Base):
    """
    Membership fee records for companies.
    Tracks monthly payments from Norda Biznes members.
    """
    __tablename__ = 'membership_fees'

    id = Column(Integer, primary_key=True)
    company_id = Column(Integer, ForeignKey('companies.id', ondelete='CASCADE'), nullable=False, index=True)

    # Period identification
    fee_year = Column(Integer, nullable=False)  # e.g., 2026
    fee_month = Column(Integer, nullable=False)  # 1-12

    # Fee details
    amount = Column(Numeric(10, 2), nullable=False)  # Amount due in PLN
    amount_paid = Column(Numeric(10, 2), default=0)  # Amount actually paid

    # Payment status: pending, paid, partial, overdue, waived
    status = Column(String(20), default='pending', index=True)

    # Payment tracking
    payment_date = Column(Date)
    payment_method = Column(String(50))  # transfer, cash, card, other
    payment_reference = Column(String(100))  # Bank transfer reference

    # Admin tracking
    recorded_by = Column(Integer, ForeignKey('users.id'))
    recorded_at = Column(DateTime)

    notes = Column(Text)

    created_at = Column(DateTime, default=datetime.now)
    updated_at = Column(DateTime, default=datetime.now, onupdate=datetime.now)

    # Relationships
    company = relationship('Company', backref='membership_fees')
    recorded_by_user = relationship('User', foreign_keys=[recorded_by])

    __table_args__ = (
        UniqueConstraint('company_id', 'fee_year', 'fee_month', name='uq_company_fee_period'),
    )

    @property
    def is_fully_paid(self):
        return (self.amount_paid or 0) >= self.amount

    @property
    def outstanding_amount(self):
        return max(0, float(self.amount) - float(self.amount_paid or 0))


class MembershipFeeConfig(Base):
    """
    Configuration for membership fees.
    Allows variable amounts per company or category.
    """
    __tablename__ = 'membership_fee_config'

    id = Column(Integer, primary_key=True)

    # Scope: global, category, or company
    scope = Column(String(20), nullable=False)  # 'global', 'category', 'company'
    category_id = Column(Integer, ForeignKey('categories.id'), nullable=True)
    company_id = Column(Integer, ForeignKey('companies.id'), nullable=True)

    monthly_amount = Column(Numeric(10, 2), nullable=False)

    valid_from = Column(Date, nullable=False)
    valid_until = Column(Date)  # NULL = currently active

    created_by = Column(Integer, ForeignKey('users.id'))
    created_at = Column(DateTime, default=datetime.now)
    notes = Column(Text)

    # Relationships
    category = relationship('Category')
    company = relationship('Company')


# ============================================================
# DATABASE INITIALIZATION
# ============================================================

def init_db():
    """Initialize database - create all tables"""
    # Import all models to ensure they're registered
    # (already done at module level)

    # Create tables (only creates if they don't exist)
    Base.metadata.create_all(bind=engine)

    print("Database tables created successfully!")


def drop_all_tables():
    """Drop all tables - USE WITH CAUTION!"""
    Base.metadata.drop_all(bind=engine)
    print("All tables dropped!")


if __name__ == '__main__':
    # Test database connection
    try:
        init_db()
        print("✅ Database initialized successfully")

        # Test query
        db = SessionLocal()
        try:
            count = db.query(Company).count()
            print(f"✅ Database connected. Found {count} companies.")
        finally:
            db.close()

    except Exception as e:
        print(f"❌ Database error: {e}")
