"""
Contacts Routes
===============

External contacts management - page endpoints only.
API endpoints (/api/contacts/*) remain in app.py for backwards compatibility.
"""

import json
import logging
from datetime import datetime
from flask import render_template, request, redirect, url_for, flash, current_app
from flask_login import login_required, current_user
from sqlalchemy import or_

from . import bp
from database import SessionLocal, ExternalContact

logger = logging.getLogger(__name__)


@bp.route('/', endpoint='contacts_list')
@login_required
def list():
    """
    Lista kontaktów zewnętrznych - urzędy, instytucje, partnerzy.
    Dostępna dla wszystkich zalogowanych członków.
    """
    db = SessionLocal()
    try:
        page = request.args.get('page', 1, type=int)
        per_page = 20
        search = request.args.get('q', '').strip()
        org_type = request.args.get('type', '')
        project = request.args.get('project', '')

        query = db.query(ExternalContact).filter(ExternalContact.is_active == True)

        # Search filter
        if search:
            search_pattern = f'%{search}%'
            query = query.filter(
                or_(
                    ExternalContact.first_name.ilike(search_pattern),
                    ExternalContact.last_name.ilike(search_pattern),
                    ExternalContact.organization_name.ilike(search_pattern),
                    ExternalContact.position.ilike(search_pattern),
                    ExternalContact.project_name.ilike(search_pattern),
                    ExternalContact.tags.ilike(search_pattern)
                )
            )

        # Organization type filter
        if org_type and org_type in ExternalContact.ORGANIZATION_TYPES:
            query = query.filter(ExternalContact.organization_type == org_type)

        # Project filter
        if project:
            query = query.filter(ExternalContact.project_name.ilike(f'%{project}%'))

        # Order by organization name, then last name
        query = query.order_by(
            ExternalContact.organization_name,
            ExternalContact.last_name
        )

        # Pagination
        total = query.count()
        contacts = query.offset((page - 1) * per_page).limit(per_page).all()
        total_pages = (total + per_page - 1) // per_page

        # Get unique projects for filter dropdown
        projects = db.query(ExternalContact.project_name).filter(
            ExternalContact.is_active == True,
            ExternalContact.project_name.isnot(None),
            ExternalContact.project_name != ''
        ).distinct().order_by(ExternalContact.project_name).all()
        project_names = [p[0] for p in projects if p[0]]

        return render_template('contacts/list.html',
                               contacts=contacts,
                               page=page,
                               total_pages=total_pages,
                               total=total,
                               search=search,
                               org_type=org_type,
                               project=project,
                               org_types=ExternalContact.ORGANIZATION_TYPES,
                               org_type_labels=ExternalContact.ORGANIZATION_TYPE_LABELS,
                               project_names=project_names)

    finally:
        db.close()


@bp.route('/<int:contact_id>', endpoint='contact_detail')
@login_required
def detail(contact_id):
    """
    Szczegóły kontaktu zewnętrznego - pełna karta osoby.
    """
    db = SessionLocal()
    try:
        contact = db.query(ExternalContact).filter(
            ExternalContact.id == contact_id,
            ExternalContact.is_active == True
        ).first()

        if not contact:
            flash('Kontakt nie został znaleziony.', 'error')
            return redirect(url_for('.contacts_list'))

        # Get other contacts from the same organization
        related_contacts = db.query(ExternalContact).filter(
            ExternalContact.organization_name == contact.organization_name,
            ExternalContact.id != contact.id,
            ExternalContact.is_active == True
        ).order_by(ExternalContact.last_name).limit(5).all()

        # Check if current user can edit (creator or admin)
        can_edit = (current_user.is_admin or
                    (contact.created_by and contact.created_by == current_user.id))

        return render_template('contacts/detail.html',
                               contact=contact,
                               related_contacts=related_contacts,
                               can_edit=can_edit,
                               org_type_labels=ExternalContact.ORGANIZATION_TYPE_LABELS)

    finally:
        db.close()


@bp.route('/dodaj', methods=['GET', 'POST'], endpoint='contact_add')
@login_required
def add():
    """
    Dodawanie nowego kontaktu zewnętrznego.
    Każdy zalogowany użytkownik może dodać kontakt.
    """
    if request.method == 'POST':
        db = SessionLocal()
        try:
            # Parse related_links from form (JSON)
            related_links_json = request.form.get('related_links', '[]')
            try:
                related_links = json.loads(related_links_json) if related_links_json else []
            except json.JSONDecodeError:
                related_links = []

            contact = ExternalContact(
                first_name=request.form.get('first_name', '').strip(),
                last_name=request.form.get('last_name', '').strip(),
                position=request.form.get('position', '').strip() or None,
                photo_url=request.form.get('photo_url', '').strip() or None,
                phone=request.form.get('phone', '').strip() or None,
                phone_secondary=request.form.get('phone_secondary', '').strip() or None,
                email=request.form.get('email', '').strip() or None,
                website=request.form.get('website', '').strip() or None,
                linkedin_url=request.form.get('linkedin_url', '').strip() or None,
                facebook_url=request.form.get('facebook_url', '').strip() or None,
                twitter_url=request.form.get('twitter_url', '').strip() or None,
                organization_name=request.form.get('organization_name', '').strip(),
                organization_type=request.form.get('organization_type', 'other'),
                organization_address=request.form.get('organization_address', '').strip() or None,
                organization_website=request.form.get('organization_website', '').strip() or None,
                organization_logo_url=request.form.get('organization_logo_url', '').strip() or None,
                project_name=request.form.get('project_name', '').strip() or None,
                project_description=request.form.get('project_description', '').strip() or None,
                source_type='manual',
                source_url=request.form.get('source_url', '').strip() or None,
                related_links=related_links,
                tags=request.form.get('tags', '').strip() or None,
                notes=request.form.get('notes', '').strip() or None,
                created_by=current_user.id
            )

            db.add(contact)
            db.commit()

            flash(f'Kontakt {contact.full_name} został dodany.', 'success')
            return redirect(url_for('.contact_detail', contact_id=contact.id))

        except Exception as e:
            db.rollback()
            current_app.logger.error(f"Error adding contact: {e}")
            flash('Wystąpił błąd podczas dodawania kontaktu.', 'error')

        finally:
            db.close()

    # GET - show form
    return render_template('contacts/form.html',
                           contact=None,
                           org_types=ExternalContact.ORGANIZATION_TYPES,
                           org_type_labels=ExternalContact.ORGANIZATION_TYPE_LABELS)


@bp.route('/<int:contact_id>/edytuj', methods=['GET', 'POST'], endpoint='contact_edit')
@login_required
def edit(contact_id):
    """
    Edycja kontaktu zewnętrznego.
    Może edytować twórca kontaktu lub admin.
    """
    db = SessionLocal()
    try:
        contact = db.query(ExternalContact).filter(
            ExternalContact.id == contact_id
        ).first()

        if not contact:
            flash('Kontakt nie został znaleziony.', 'error')
            return redirect(url_for('.contacts_list'))

        # Check permissions
        if not current_user.is_admin and contact.created_by != current_user.id:
            flash('Nie masz uprawnień do edycji tego kontaktu.', 'error')
            return redirect(url_for('.contact_detail', contact_id=contact_id))

        if request.method == 'POST':
            # Parse related_links from form (JSON)
            related_links_json = request.form.get('related_links', '[]')
            try:
                related_links = json.loads(related_links_json) if related_links_json else []
            except json.JSONDecodeError:
                related_links = contact.related_links or []

            contact.first_name = request.form.get('first_name', '').strip()
            contact.last_name = request.form.get('last_name', '').strip()
            contact.position = request.form.get('position', '').strip() or None
            contact.photo_url = request.form.get('photo_url', '').strip() or None
            contact.phone = request.form.get('phone', '').strip() or None
            contact.phone_secondary = request.form.get('phone_secondary', '').strip() or None
            contact.email = request.form.get('email', '').strip() or None
            contact.website = request.form.get('website', '').strip() or None
            contact.linkedin_url = request.form.get('linkedin_url', '').strip() or None
            contact.facebook_url = request.form.get('facebook_url', '').strip() or None
            contact.twitter_url = request.form.get('twitter_url', '').strip() or None
            contact.organization_name = request.form.get('organization_name', '').strip()
            contact.organization_type = request.form.get('organization_type', 'other')
            contact.organization_address = request.form.get('organization_address', '').strip() or None
            contact.organization_website = request.form.get('organization_website', '').strip() or None
            contact.organization_logo_url = request.form.get('organization_logo_url', '').strip() or None
            contact.project_name = request.form.get('project_name', '').strip() or None
            contact.project_description = request.form.get('project_description', '').strip() or None
            contact.source_url = request.form.get('source_url', '').strip() or None
            contact.related_links = related_links
            contact.tags = request.form.get('tags', '').strip() or None
            contact.notes = request.form.get('notes', '').strip() or None
            contact.updated_at = datetime.now()

            db.commit()

            flash(f'Kontakt {contact.full_name} został zaktualizowany.', 'success')
            return redirect(url_for('.contact_detail', contact_id=contact.id))

        # GET - show form with existing data
        return render_template('contacts/form.html',
                               contact=contact,
                               org_types=ExternalContact.ORGANIZATION_TYPES,
                               org_type_labels=ExternalContact.ORGANIZATION_TYPE_LABELS)

    finally:
        db.close()


@bp.route('/<int:contact_id>/usun', methods=['POST'], endpoint='contact_delete')
@login_required
def delete(contact_id):
    """
    Usuwanie kontaktu zewnętrznego (soft delete).
    Może usunąć twórca kontaktu lub admin.
    """
    db = SessionLocal()
    try:
        contact = db.query(ExternalContact).filter(
            ExternalContact.id == contact_id
        ).first()

        if not contact:
            flash('Kontakt nie został znaleziony.', 'error')
            return redirect(url_for('.contacts_list'))

        # Check permissions
        if not current_user.is_admin and contact.created_by != current_user.id:
            flash('Nie masz uprawnień do usunięcia tego kontaktu.', 'error')
            return redirect(url_for('.contact_detail', contact_id=contact_id))

        # Soft delete
        contact.is_active = False
        contact.updated_at = datetime.now()
        db.commit()

        flash(f'Kontakt {contact.full_name} został usunięty.', 'success')
        return redirect(url_for('.contacts_list'))

    finally:
        db.close()
