from datetime import datetime, timezone, timedelta
from flask import render_template, request, jsonify, current_app, flash, redirect, url_for
from flask_mail import Message

from app.work_with_us import work_with_us_bp
from app.work_with_us.forms import WorkWithUsForm
from app.models import CollaborationRequest
from app.extensions import db, mail


def get_client_ip():
    """Retrieve real client IP behind reverse proxies safely."""
    forwarded_for = request.headers.get('X-Forwarded-For')
    if forwarded_for:
        return forwarded_for.split(',')[0].strip()
    return request.remote_addr or "127.0.0.1"


def extract_first_error(err_data):
    """Safely retrieve the first error message string to clear Pylance/Type warnings."""
    if isinstance(err_data, dict):
        return str(next(iter(err_data.values()), "Invalid input"))
    if isinstance(err_data, (list, tuple)) and err_data:
        return str(err_data[0])
    return "Invalid input"


@work_with_us_bp.route("/work-with-us", methods=["GET", "POST"], endpoint="index")
def index():
    form = WorkWithUsForm()

    if request.method == "POST":
        client_ip = get_client_ip()
        one_hour_ago = datetime.now(timezone.utc) - timedelta(hours=1)

        # 1. Rate Limiting Check (1 submission per IP per hour)
        recent_submission = CollaborationRequest.query.filter(
            CollaborationRequest.ip_address == client_ip,
            CollaborationRequest.created_at >= one_hour_ago
        ).order_by(CollaborationRequest.created_at.desc()).first()

        if recent_submission:
            created_at = recent_submission.created_at
            if created_at.tzinfo is None:
                created_at = created_at.replace(tzinfo=timezone.utc)

            time_passed = datetime.now(timezone.utc) - created_at
            seconds_remaining = int(3600 - time_passed.total_seconds())
            minutes_remaining = max(1, (seconds_remaining + 59) // 60)

            err_msg = f"You can only submit one proposal per hour. Please wait {minutes_remaining} minute(s) before trying again."

            if request.headers.get('X-Requested-With') == 'XMLHttpRequest' or request.is_json:
                return jsonify({'success': False, 'message': err_msg}), 429

            flash(err_msg, 'warning')
            return render_template("pages/work_with_us.html", form=form), 429

        # 2. Form Processing & CSRF Validation
        if form.validate_on_submit():
            try:
                # Handle field matching between WTForms and SQLAlchemy Model
                privacy_field = getattr(form, 'privacy_consent', None) or getattr(form, 'agreement', None)
                agreement_val = bool(privacy_field.data) if privacy_field else False

                proposal = CollaborationRequest(
                    name=form.name.data.strip() if form.name.data else "",
                    email=form.email.data.strip() if form.email.data else "",
                    phone=form.phone.data.strip() if form.phone.data else None,
                    organisation=form.organisation.data.strip() if form.organisation.data else None,
                    role=form.role.data.strip() if form.role.data else None,
                    website=form.website.data.strip() if form.website.data else None,
                    collaboration_type=form.collaboration_type.data,
                    contribution=form.contribution.data.strip() if form.contribution.data else "",
                    support_requested=form.support_requested.data.strip() if form.support_requested.data else "",
                    message=form.message.data.strip() if form.message.data else None,
                    agreement=agreement_val,
                    ip_address=client_ip
                )
                db.session.add(proposal)
                db.session.commit()

                send_collaboration_emails(proposal)

                success_msg = "Thank you! Your proposal has been submitted successfully."

                if request.headers.get('X-Requested-With') == 'XMLHttpRequest' or request.is_json:
                    return jsonify({'success': True, 'message': success_msg}), 200

                flash(success_msg, 'success')
                return redirect(url_for('work_with_us.index'))

            except Exception as e:
                db.session.rollback()
                current_app.logger.error(f"Collaboration proposal failed: {e}")
                err_msg = "An internal server error occurred while processing your proposal."

                if request.headers.get('X-Requested-With') == 'XMLHttpRequest' or request.is_json:
                    return jsonify({'success': False, 'message': err_msg}), 500

                flash(err_msg, 'danger')

        # 3. Handle Validation / CSRF Errors for AJAX (Fixes 400 Bad Request Payload)
        if request.headers.get('X-Requested-With') == 'XMLHttpRequest' or request.is_json:
            formatted_errors = {
                field: extract_first_error(err_data)
                for field, err_data in form.errors.items()
            }
            first_msg = next(iter(formatted_errors.values()), "Please fix the validation errors below.")

            return jsonify({
                'success': False,
                'message': first_msg,
                'errors': formatted_errors
            }), 400

    return render_template("pages/work_with_us.html", form=form)


def send_collaboration_emails(proposal):
    """Sends notification email to admin and confirmation email to applicant."""
    try:
        admin_email = (
            current_app.config.get("ADMIN_EMAIL")
            or current_app.config.get("MAIL_DEFAULT_SENDER")
            or "contact@codnesta.com"
        )

        # Admin Plain-Text Fallback
        admin_msg = Message(
            subject=f"[CodNesta Proposal] {proposal.collaboration_type} - {proposal.name}",
            recipients=[str(admin_email)],
            body=(
                f"New Collaboration Proposal Received:\n\n"
                f"Name: {proposal.name}\n"
                f"Email: {proposal.email}\n"
                f"Phone: {proposal.phone or 'N/A'}\n"
                f"Organisation: {proposal.organisation or 'N/A'}\n"
                f"Role: {proposal.role or 'N/A'}\n"
                f"Website: {proposal.website or 'N/A'}\n\n"
                f"Collaboration Type: {proposal.collaboration_type}\n\n"
                f"Contribution Offered:\n{proposal.contribution}\n\n"
                f"Support Requested:\n{proposal.support_requested}\n\n"
                f"Additional Message:\n{proposal.message or 'N/A'}"
            )
        )

        # Client Plain-Text Fallback
        user_msg = Message(
            subject="We've received your proposal | CodNesta Partnerships",
            recipients=[str(proposal.email)],
            body=(
                f"Hello {proposal.name},\n\n"
                f"Thank you for reaching out to CodNesta regarding a '{proposal.collaboration_type}' proposal. "
                f"Our team will review your submission and follow up shortly.\n\n"
                f"Connect with us:\n"
                f"- Facebook: https://web.facebook.com/CodNesta\n"
                f"- LinkedIn: https://www.linkedin.com/company/codnesta\n\n"
                f"Best regards,\nCodNesta Partnerships Team"
            )
        )

        # HTML Templates Rendering
        try:
            formatted_date = datetime.now(timezone.utc).strftime("%B %d, %Y at %I:%M %p UTC")
            current_year = datetime.now().year

            admin_msg.html = render_template(
                "emails/work/collaboration-admin.html",
                submission=proposal,
                created_at=formatted_date
            )

            user_msg.html = render_template(
                "emails/work/collaboration-client.html",
                submission=proposal,
                current_year=current_year
            )
        except Exception as render_err:
            current_app.logger.warning(
                f"Could not render Work With Us HTML email templates, falling back to plain text: {render_err}"
            )

        mail.send(admin_msg)
        mail.send(user_msg)
    except Exception as e:
        current_app.logger.error(f"Failed to send collaboration emails: {e}")