"""
Classifieds Routes
==================

B2B bulletin board endpoints.
"""

from datetime import datetime, timedelta
from flask import render_template, request, redirect, url_for, flash, jsonify
from flask_login import login_required, current_user

from . import bp
from database import SessionLocal, Classified, ClassifiedRead, ClassifiedInterest, ClassifiedQuestion, User
from sqlalchemy import desc
from utils.helpers import sanitize_input
from utils.decorators import member_required


@bp.route('/', endpoint='classifieds_index')
@login_required
@member_required
def index():
    """Tablica ogłoszeń B2B"""
    listing_type = request.args.get('type', '')
    category = request.args.get('category', '')
    page = request.args.get('page', 1, type=int)
    per_page = 20

    db = SessionLocal()
    try:
        query = db.query(Classified).filter(
            Classified.is_active == True
        )

        # Filtry
        if listing_type:
            query = query.filter(Classified.listing_type == listing_type)
        if category:
            query = query.filter(Classified.category == category)

        # Sortowanie - najnowsze pierwsze
        query = query.order_by(Classified.created_at.desc())

        total = query.count()
        classifieds = query.limit(per_page).offset((page - 1) * per_page).all()

        # Kategorie do filtrów
        categories = [
            ('uslugi', 'Usługi'),
            ('produkty', 'Produkty'),
            ('wspolpraca', 'Współpraca'),
            ('praca', 'Praca'),
            ('inne', 'Inne')
        ]

        return render_template('classifieds/index.html',
            classifieds=classifieds,
            categories=categories,
            listing_type=listing_type,
            category_filter=category,
            page=page,
            total_pages=(total + per_page - 1) // per_page
        )
    finally:
        db.close()


@bp.route('/nowe', methods=['GET', 'POST'], endpoint='classifieds_new')
@login_required
@member_required
def new():
    """Dodaj nowe ogłoszenie"""
    if request.method == 'POST':
        listing_type = request.form.get('listing_type', '')
        category = request.form.get('category', '')
        title = sanitize_input(request.form.get('title', ''), 255)
        description = request.form.get('description', '').strip()
        budget_info = sanitize_input(request.form.get('budget_info', ''), 255)
        location_info = sanitize_input(request.form.get('location_info', ''), 255)

        if not listing_type or not category or not title or not description:
            flash('Wszystkie wymagane pola muszą być wypełnione.', 'error')
            return render_template('classifieds/new.html')

        db = SessionLocal()
        try:
            # Automatyczne wygaśnięcie po 30 dniach
            expires = datetime.now() + timedelta(days=30)

            classified = Classified(
                author_id=current_user.id,
                company_id=current_user.company_id,
                listing_type=listing_type,
                category=category,
                title=title,
                description=description,
                budget_info=budget_info,
                location_info=location_info,
                expires_at=expires
            )
            db.add(classified)
            db.commit()

            flash('Ogłoszenie dodane.', 'success')
            return redirect(url_for('.classifieds_index'))
        finally:
            db.close()

    return render_template('classifieds/new.html')


@bp.route('/<int:classified_id>', endpoint='classifieds_view')
@login_required
@member_required
def view(classified_id):
    """Szczegóły ogłoszenia"""
    db = SessionLocal()
    try:
        classified = db.query(Classified).filter(
            Classified.id == classified_id
        ).first()

        if not classified:
            flash('Ogłoszenie nie istnieje.', 'error')
            return redirect(url_for('.classifieds_index'))

        # Zwiększ licznik wyświetleń (handle NULL)
        classified.views_count = (classified.views_count or 0) + 1

        # Zapisz odczyt przez zalogowanego użytkownika
        existing_read = db.query(ClassifiedRead).filter(
            ClassifiedRead.classified_id == classified.id,
            ClassifiedRead.user_id == current_user.id
        ).first()

        if not existing_read:
            new_read = ClassifiedRead(
                classified_id=classified.id,
                user_id=current_user.id
            )
            db.add(new_read)

        db.commit()

        # Pobierz listę czytelników
        readers = db.query(ClassifiedRead).filter(
            ClassifiedRead.classified_id == classified.id
        ).order_by(desc(ClassifiedRead.read_at)).all()
        readers_count = len(readers)

        # Sprawdź czy użytkownik jest zainteresowany
        user_interested = db.query(ClassifiedInterest).filter(
            ClassifiedInterest.classified_id == classified.id,
            ClassifiedInterest.user_id == current_user.id
        ).first() is not None

        # Liczba zainteresowanych
        interests_count = db.query(ClassifiedInterest).filter(
            ClassifiedInterest.classified_id == classified.id
        ).count()

        # Pobierz pytania (publiczne dla wszystkich, wszystkie dla autora)
        questions_query = db.query(ClassifiedQuestion).filter(
            ClassifiedQuestion.classified_id == classified.id
        )
        if classified.author_id != current_user.id and not current_user.can_access_admin_panel():
            questions_query = questions_query.filter(ClassifiedQuestion.is_public == True)
        questions = questions_query.order_by(ClassifiedQuestion.created_at.asc()).all()

        # Liczba pytań bez odpowiedzi (dla autora)
        unanswered_count = 0
        if classified.author_id == current_user.id:
            unanswered_count = db.query(ClassifiedQuestion).filter(
                ClassifiedQuestion.classified_id == classified.id,
                ClassifiedQuestion.answer == None
            ).count()

        return render_template('classifieds/view.html',
                               classified=classified,
                               readers=readers,
                               readers_count=readers_count,
                               user_interested=user_interested,
                               interests_count=interests_count,
                               questions=questions,
                               unanswered_count=unanswered_count)
    finally:
        db.close()


@bp.route('/<int:classified_id>/zakoncz', methods=['POST'], endpoint='classifieds_close')
@login_required
@member_required
def close(classified_id):
    """Zamknij ogłoszenie"""
    db = SessionLocal()
    try:
        classified = db.query(Classified).filter(
            Classified.id == classified_id,
            Classified.author_id == current_user.id
        ).first()

        if not classified:
            return jsonify({'success': False, 'error': 'Ogłoszenie nie istnieje lub brak uprawnień'}), 404

        classified.is_active = False
        db.commit()

        return jsonify({'success': True, 'message': 'Ogłoszenie zamknięte'})
    finally:
        db.close()


@bp.route('/<int:classified_id>/delete', methods=['POST'], endpoint='classifieds_delete')
@login_required
@member_required
def delete(classified_id):
    """Usuń ogłoszenie (admin only)"""
    if not current_user.can_access_admin_panel():
        return jsonify({'success': False, 'error': 'Brak uprawnień'}), 403

    db = SessionLocal()
    try:
        classified = db.query(Classified).filter(
            Classified.id == classified_id
        ).first()

        if not classified:
            return jsonify({'success': False, 'error': 'Ogłoszenie nie istnieje'}), 404

        db.delete(classified)
        db.commit()

        return jsonify({'success': True, 'message': 'Ogłoszenie usunięte'})
    finally:
        db.close()


@bp.route('/<int:classified_id>/toggle-active', methods=['POST'], endpoint='classifieds_toggle_active')
@login_required
@member_required
def toggle_active(classified_id):
    """Aktywuj/dezaktywuj ogłoszenie (admin only)"""
    if not current_user.can_access_admin_panel():
        return jsonify({'success': False, 'error': 'Brak uprawnień'}), 403

    db = SessionLocal()
    try:
        classified = db.query(Classified).filter(
            Classified.id == classified_id
        ).first()

        if not classified:
            return jsonify({'success': False, 'error': 'Ogłoszenie nie istnieje'}), 404

        classified.is_active = not classified.is_active
        db.commit()

        status = 'aktywowane' if classified.is_active else 'dezaktywowane'
        return jsonify({'success': True, 'message': f'Ogłoszenie {status}', 'is_active': classified.is_active})
    finally:
        db.close()


# ============================================================
# INTEREST (ZAINTERESOWANIA)
# ============================================================

@bp.route('/<int:classified_id>/interest', methods=['POST'], endpoint='classifieds_interest')
@login_required
@member_required
def toggle_interest(classified_id):
    """Toggle zainteresowania ogłoszeniem"""
    db = SessionLocal()
    try:
        classified = db.query(Classified).filter(
            Classified.id == classified_id,
            Classified.is_active == True
        ).first()

        if not classified:
            return jsonify({'success': False, 'error': 'Ogłoszenie nie istnieje lub jest nieaktywne'}), 404

        # Nie można być zainteresowanym własnym ogłoszeniem
        if classified.author_id == current_user.id:
            return jsonify({'success': False, 'error': 'Nie możesz być zainteresowany własnym ogłoszeniem'}), 400

        # Sprawdź czy już jest zainteresowany
        existing = db.query(ClassifiedInterest).filter(
            ClassifiedInterest.classified_id == classified_id,
            ClassifiedInterest.user_id == current_user.id
        ).first()

        if existing:
            # Usuń zainteresowanie
            db.delete(existing)
            db.commit()
            return jsonify({
                'success': True,
                'interested': False,
                'message': 'Usunięto zainteresowanie'
            })
        else:
            # Dodaj zainteresowanie
            message = request.json.get('message', '') if request.is_json else ''
            interest = ClassifiedInterest(
                classified_id=classified_id,
                user_id=current_user.id,
                message=message[:255] if message else None
            )
            db.add(interest)
            db.commit()
            return jsonify({
                'success': True,
                'interested': True,
                'message': 'Dodano zainteresowanie'
            })
    finally:
        db.close()


@bp.route('/<int:classified_id>/interests', endpoint='classifieds_interests')
@login_required
@member_required
def list_interests(classified_id):
    """Lista zainteresowanych (tylko dla autora ogłoszenia)"""
    db = SessionLocal()
    try:
        classified = db.query(Classified).filter(
            Classified.id == classified_id
        ).first()

        if not classified:
            return jsonify({'success': False, 'error': 'Ogłoszenie nie istnieje'}), 404

        # Tylko autor może widzieć pełną listę (lub admin)
        if classified.author_id != current_user.id and not current_user.can_access_admin_panel():
            return jsonify({'success': False, 'error': 'Brak uprawnień'}), 403

        interests = db.query(ClassifiedInterest).filter(
            ClassifiedInterest.classified_id == classified_id
        ).order_by(desc(ClassifiedInterest.created_at)).all()

        return jsonify({
            'success': True,
            'count': len(interests),
            'interests': [
                {
                    'id': i.id,
                    'user_id': i.user_id,
                    'user_name': i.user.name or i.user.email.split('@')[0],
                    'user_initial': (i.user.name or i.user.email)[0].upper(),
                    'company_name': i.user.company.name if i.user.company else None,
                    'message': i.message,
                    'created_at': i.created_at.isoformat() if i.created_at else None
                }
                for i in interests
            ]
        })
    finally:
        db.close()


# ============================================================
# Q&A (PYTANIA I ODPOWIEDZI)
# ============================================================

@bp.route('/<int:classified_id>/ask', methods=['POST'], endpoint='classifieds_ask')
@login_required
@member_required
def ask_question(classified_id):
    """Zadaj pytanie do ogłoszenia"""
    db = SessionLocal()
    try:
        classified = db.query(Classified).filter(
            Classified.id == classified_id,
            Classified.is_active == True
        ).first()

        if not classified:
            return jsonify({'success': False, 'error': 'Ogłoszenie nie istnieje lub jest nieaktywne'}), 404

        content = ''
        if request.is_json:
            content = request.json.get('content', '').strip()
        else:
            content = request.form.get('content', '').strip()

        if not content:
            return jsonify({'success': False, 'error': 'Treść pytania jest wymagana'}), 400

        if len(content) > 2000:
            return jsonify({'success': False, 'error': 'Pytanie jest zbyt długie (max 2000 znaków)'}), 400

        question = ClassifiedQuestion(
            classified_id=classified_id,
            author_id=current_user.id,
            content=content
        )
        db.add(question)
        db.commit()

        return jsonify({
            'success': True,
            'message': 'Pytanie dodane',
            'question': {
                'id': question.id,
                'content': question.content,
                'author_name': current_user.name or current_user.email.split('@')[0],
                'created_at': question.created_at.isoformat()
            }
        })
    finally:
        db.close()


@bp.route('/<int:classified_id>/question/<int:question_id>/answer', methods=['POST'], endpoint='classifieds_answer')
@login_required
@member_required
def answer_question(classified_id, question_id):
    """Odpowiedz na pytanie (tylko autor ogłoszenia)"""
    db = SessionLocal()
    try:
        classified = db.query(Classified).filter(
            Classified.id == classified_id
        ).first()

        if not classified:
            return jsonify({'success': False, 'error': 'Ogłoszenie nie istnieje'}), 404

        # Tylko autor ogłoszenia może odpowiadać
        if classified.author_id != current_user.id:
            return jsonify({'success': False, 'error': 'Tylko autor ogłoszenia może odpowiadać na pytania'}), 403

        question = db.query(ClassifiedQuestion).filter(
            ClassifiedQuestion.id == question_id,
            ClassifiedQuestion.classified_id == classified_id
        ).first()

        if not question:
            return jsonify({'success': False, 'error': 'Pytanie nie istnieje'}), 404

        answer = ''
        if request.is_json:
            answer = request.json.get('answer', '').strip()
        else:
            answer = request.form.get('answer', '').strip()

        if not answer:
            return jsonify({'success': False, 'error': 'Treść odpowiedzi jest wymagana'}), 400

        if len(answer) > 2000:
            return jsonify({'success': False, 'error': 'Odpowiedź jest zbyt długa (max 2000 znaków)'}), 400

        question.answer = answer
        question.answered_by = current_user.id
        question.answered_at = datetime.now()
        db.commit()

        return jsonify({
            'success': True,
            'message': 'Odpowiedź dodana',
            'answer': answer,
            'answered_at': question.answered_at.isoformat()
        })
    finally:
        db.close()


@bp.route('/<int:classified_id>/question/<int:question_id>/hide', methods=['POST'], endpoint='classifieds_hide_question')
@login_required
@member_required
def hide_question(classified_id, question_id):
    """Ukryj/pokaż pytanie (tylko autor ogłoszenia)"""
    db = SessionLocal()
    try:
        classified = db.query(Classified).filter(
            Classified.id == classified_id
        ).first()

        if not classified:
            return jsonify({'success': False, 'error': 'Ogłoszenie nie istnieje'}), 404

        # Tylko autor ogłoszenia lub admin może ukrywać
        if classified.author_id != current_user.id and not current_user.can_access_admin_panel():
            return jsonify({'success': False, 'error': 'Brak uprawnień'}), 403

        question = db.query(ClassifiedQuestion).filter(
            ClassifiedQuestion.id == question_id,
            ClassifiedQuestion.classified_id == classified_id
        ).first()

        if not question:
            return jsonify({'success': False, 'error': 'Pytanie nie istnieje'}), 404

        question.is_public = not question.is_public
        db.commit()

        status = 'widoczne' if question.is_public else 'ukryte'
        return jsonify({
            'success': True,
            'message': f'Pytanie jest teraz {status}',
            'is_public': question.is_public
        })
    finally:
        db.close()


@bp.route('/<int:classified_id>/questions', endpoint='classifieds_questions')
@login_required
@member_required
def list_questions(classified_id):
    """Lista pytań i odpowiedzi do ogłoszenia"""
    db = SessionLocal()
    try:
        classified = db.query(Classified).filter(
            Classified.id == classified_id
        ).first()

        if not classified:
            return jsonify({'success': False, 'error': 'Ogłoszenie nie istnieje'}), 404

        # Buduj query - autor widzi wszystkie, inni tylko publiczne
        query = db.query(ClassifiedQuestion).filter(
            ClassifiedQuestion.classified_id == classified_id
        )

        if classified.author_id != current_user.id and not current_user.can_access_admin_panel():
            query = query.filter(ClassifiedQuestion.is_public == True)

        questions = query.order_by(desc(ClassifiedQuestion.created_at)).all()

        return jsonify({
            'success': True,
            'count': len(questions),
            'is_owner': classified.author_id == current_user.id,
            'questions': [
                {
                    'id': q.id,
                    'content': q.content,
                    'author_id': q.author_id,
                    'author_name': q.author.name or q.author.email.split('@')[0],
                    'author_initial': (q.author.name or q.author.email)[0].upper(),
                    'author_company': q.author.company.name if q.author.company else None,
                    'answer': q.answer,
                    'answered_at': q.answered_at.isoformat() if q.answered_at else None,
                    'is_public': q.is_public,
                    'created_at': q.created_at.isoformat() if q.created_at else None
                }
                for q in questions
            ]
        })
    finally:
        db.close()
