import stripe
from flask import Blueprint, render_template, request, redirect, url_for, flash, jsonify, current_app
from flask_login import login_required, current_user
from app.extensions import db, csrf
from app.models.features import (MarketplaceListing, MarketplacePurchase,
                                  MarketplaceInquiry, MarketplaceReview, Notification)
from app.models.report import Report
from functools import wraps

marketplace_bp = Blueprint("marketplace", __name__, url_prefix="/marketplace")


def premium_required(f):
    """Decorator to require premium subscription for route access."""
    @wraps(f)
    @login_required
    def decorated(*args, **kwargs):
        if not current_user.has_premium_access:
            flash("هذه الميزة متاحة فقط للمشتركين في الخطط المدفوعة", "warning")
            return redirect(url_for('subscription.plans'))
        return f(*args, **kwargs)
    return decorated

SA_SECTORS = [
    "تقنية المعلومات", "تجارة إلكترونية", "مطاعم وأغذية", "عقارات",
    "استشارات", "تعليم وتدريب", "صحة وطب", "نقل ولوجستيات",
    "سياحة وترفيه", "صناعة", "زراعة", "خدمات مالية",
]

GOAL_INFO = {
    "sell": {"label": "للبيع", "icon": "🛒", "color": "gold"},
    "find_investor": {"label": "بحث عن مستثمر", "icon": "💰", "color": "emerald"},
    "find_partner": {"label": "بحث عن شريك", "icon": "🤝", "color": "blue"},
    "license": {"label": "ترخيص", "icon": "📄", "color": "purple"},
    "free": {"label": "مجاني", "icon": "🆓", "color": "slate"},
}


# ─── Public Index ───────────────────────────────────────────
@marketplace_bp.route("/")
@premium_required
def index():
    page = request.args.get("page", 1, type=int)
    goal = request.args.get("goal", "").strip()
    sector = request.args.get("sector", "").strip()
    search = request.args.get("q", "").strip()
    sort = request.args.get("sort", "newest")

    query = MarketplaceListing.query.filter_by(is_active=True, approval_status="approved")
    if goal:
        query = query.filter_by(listing_goal=goal)
    if sector:
        query = query.filter_by(sector=sector)
    if search:
        query = query.filter(
            (MarketplaceListing.title.ilike(f"%{search}%")) |
            (MarketplaceListing.description.ilike(f"%{search}%"))
        )

    if sort == "popular":
        query = query.order_by(MarketplaceListing.purchases.desc())
    elif sort == "price_low":
        query = query.order_by(MarketplaceListing.price.asc())
    elif sort == "price_high":
        query = query.order_by(MarketplaceListing.price.desc())
    else:
        query = query.order_by(MarketplaceListing.featured.desc(), MarketplaceListing.created_at.desc())

    featured = MarketplaceListing.query.filter_by(
        is_active=True, approval_status="approved", featured=True
    ).order_by(MarketplaceListing.created_at.desc()).limit(3).all() if not goal and not search else []

    pagination = query.paginate(page=page, per_page=12, error_out=False)
    return render_template("marketplace/index.html",
        pagination=pagination, sector=sector, goal=goal, search=search, sort=sort,
        sectors=SA_SECTORS, goal_info=GOAL_INFO, featured_listings=featured)


# ─── View Listing Detail ───────────────────────────────────
@marketplace_bp.route("/view/<int:listing_id>")
def view_listing(listing_id):
    listing = MarketplaceListing.query.get_or_404(listing_id)
    if not listing.is_active and (not current_user.is_authenticated or
        (listing.user_id != current_user.id and not current_user.is_admin)):
        flash("هذه الدراسة غير متاحة حالياً.", "error")
        return redirect(url_for("marketplace.index"))

    listing.views += 1
    db.session.commit()

    already_purchased = False
    user_inquiry = None
    if current_user.is_authenticated:
        already_purchased = MarketplacePurchase.query.filter_by(
            listing_id=listing_id, buyer_id=current_user.id, status="completed"
        ).first() is not None
        user_inquiry = MarketplaceInquiry.query.filter_by(
            listing_id=listing_id, sender_id=current_user.id
        ).first()

    reviews = MarketplaceReview.query.filter_by(listing_id=listing_id).order_by(
        MarketplaceReview.created_at.desc()).all()
    seller_sales = MarketplacePurchase.query.join(MarketplaceListing).filter(
        MarketplaceListing.user_id == listing.user_id,
        MarketplacePurchase.status == "completed"
    ).count()

    return render_template("marketplace/view.html",
        listing=listing, already_purchased=already_purchased,
        user_inquiry=user_inquiry, reviews=reviews,
        seller_sales=seller_sales, goal_info=GOAL_INFO)


# ─── Create Listing (submit for review) ────────────────────
@marketplace_bp.route("/create", methods=["GET"])
@login_required
def create():
    reports = Report.query.filter_by(user_id=current_user.id).filter(
        Report.full_report_html.isnot(None)
    ).order_by(Report.created_at.desc()).all()
    report_id = request.args.get("report_id", type=int)
    return render_template("marketplace/create.html",
        reports=reports, sectors=SA_SECTORS, goal_info=GOAL_INFO,
        preselect_report_id=report_id)


@marketplace_bp.route("/create", methods=["POST"])
@login_required
def create_post():
    report_id = request.form.get("report_id", type=int)
    report = Report.query.get_or_404(report_id)
    if report.user_id != current_user.id:
        flash("غير مصرح.", "error")
        return redirect(url_for("marketplace.index"))

    existing = MarketplaceListing.query.filter_by(report_id=report_id).first()
    if existing:
        flash("هذه الدراسة معروضة بالفعل.", "info")
        return redirect(url_for("marketplace.my_listings"))

    goal = request.form.get("listing_goal", "sell")
    if goal not in MarketplaceListing.GOAL_CHOICES:
        goal = "sell"

    listing = MarketplaceListing(
        report_id=report_id,
        user_id=current_user.id,
        listing_goal=goal,
        title=request.form.get("title", report.project_name).strip() or report.project_name,
        sector=request.form.get("sector", "").strip(),
        description=request.form.get("description", "").strip(),
        preview_text=request.form.get("preview_text", "").strip(),
        price=request.form.get("price", 0, type=float) if goal in ("sell", "license") else 0,
        currency=current_user.currency or "SAR",
        investment_needed=request.form.get("investment_needed", 0, type=float) if goal == "find_investor" else None,
        equity_offered=request.form.get("equity_offered", 0, type=float) if goal in ("find_investor", "find_partner") else None,
        partner_role=request.form.get("partner_role", "").strip() if goal == "find_partner" else None,
        license_terms=request.form.get("license_terms", "").strip() if goal == "license" else None,
        contact_email=request.form.get("contact_email", "").strip(),
        is_active=False,
        approval_status="pending",
    )
    db.session.add(listing)
    db.session.commit()

    # Notify admins
    from app.models.user import User
    admins = User.query.filter_by(is_admin=True).all()
    for admin in admins:
        notif = Notification(
            user_id=admin.id,
            title="دراسة جديدة تنتظر الموافقة",
            message=f"قدّم {current_user.name} دراسة «{listing.title}» للعرض في السوق.",
            category="marketplace",
            link=url_for("admin.marketplace_review"),
        )
        db.session.add(notif)
    db.session.commit()

    flash("تم تقديم الدراسة للمراجعة. ستظهر في السوق بعد موافقة الإدارة.", "success")
    return redirect(url_for("marketplace.my_listings"))


# ─── Purchase via Stripe ────────────────────────────────────
@marketplace_bp.route("/purchase/<int:listing_id>", methods=["POST"])
@login_required
def purchase(listing_id):
    listing = MarketplaceListing.query.get_or_404(listing_id)
    if listing.user_id == current_user.id:
        flash("لا يمكنك شراء دراستك.", "error")
        return redirect(url_for("marketplace.view_listing", listing_id=listing_id))
    if listing.listing_goal not in ("sell", "license"):
        flash("هذه الدراسة غير متاحة للشراء المباشر.", "error")
        return redirect(url_for("marketplace.view_listing", listing_id=listing_id))

    # Check if already purchased
    existing = MarketplacePurchase.query.filter_by(
        listing_id=listing_id, buyer_id=current_user.id, status="completed"
    ).first()
    if existing:
        flash("لقد اشتريت هذه الدراسة مسبقاً.", "info")
        return redirect(url_for("study.view", report_id=listing.report_id))

    stripe.api_key = current_app.config["STRIPE_SECRET_KEY"]
    if not stripe.api_key:
        flash("نظام الدفع غير مفعّل حالياً.", "error")
        return redirect(url_for("marketplace.view_listing", listing_id=listing_id))

    goal_label = "ترخيص" if listing.listing_goal == "license" else "شراء"
    try:
        session = stripe.checkout.Session.create(
            payment_method_types=["card"],
            line_items=[{
                "price_data": {
                    "currency": (listing.currency or "usd").lower(),
                    "product_data": {
                        "name": f"{goal_label}: {listing.title}",
                        "description": (listing.description or "")[:500],
                    },
                    "unit_amount": int(listing.price * 100),
                },
                "quantity": 1,
            }],
            mode="payment",
            success_url=url_for("marketplace.purchase_success", _external=True) + "?session_id={CHECKOUT_SESSION_ID}",
            cancel_url=url_for("marketplace.view_listing", listing_id=listing_id, _external=True),
            client_reference_id=str(current_user.id),
            metadata={
                "type": "marketplace",
                "listing_id": str(listing.id),
                "buyer_id": str(current_user.id),
            },
        )

        # Create pending purchase
        purchase_record = MarketplacePurchase(
            listing_id=listing_id,
            buyer_id=current_user.id,
            amount=listing.price,
            currency=listing.currency or "USD",
            stripe_session_id=session.id,
            status="pending",
        )
        db.session.add(purchase_record)
        db.session.commit()

        return redirect(session.url, code=303)
    except Exception as e:
        current_app.logger.error(f"Stripe marketplace error: {e}")
        flash(f"خطأ في الدفع: {e}", "error")
        return redirect(url_for("marketplace.view_listing", listing_id=listing_id))


@marketplace_bp.route("/purchase-success")
@login_required
def purchase_success():
    session_id = request.args.get("session_id")
    purchase_record = None
    if session_id:
        purchase_record = MarketplacePurchase.query.filter_by(
            stripe_session_id=session_id, buyer_id=current_user.id
        ).first()
        # Mark as completed if Stripe confirmed (webhook may not have fired yet)
        if purchase_record and purchase_record.status == "pending":
            try:
                stripe.api_key = current_app.config["STRIPE_SECRET_KEY"]
                session = stripe.checkout.Session.retrieve(session_id)
                if session.payment_status == "paid":
                    purchase_record.status = "completed"
                    purchase_record.stripe_payment_intent = session.payment_intent
                    purchase_record.listing.purchases += 1
                    db.session.commit()
                    # Notifications
                    _send_purchase_notifications(purchase_record)
            except Exception:
                pass
    return render_template("marketplace/purchase_success.html", purchase=purchase_record)


def _send_purchase_notifications(purchase_record):
    listing = purchase_record.listing
    # Notify seller
    seller_notif = Notification(
        user_id=listing.user_id,
        title="تم بيع دراستك! 🎉",
        message=f"اشترى أحد المستخدمين دراسة «{listing.title}» بمبلغ {purchase_record.amount} {purchase_record.currency}.",
        category="marketplace",
        link=url_for("marketplace.my_listings"),
    )
    # Notify buyer
    buyer_notif = Notification(
        user_id=purchase_record.buyer_id,
        title="تم الشراء بنجاح ✅",
        message=f"يمكنك الآن عرض دراسة «{listing.title}» بالكامل.",
        category="marketplace",
        link=url_for("study.view", report_id=listing.report_id),
    )
    db.session.add_all([seller_notif, buyer_notif])
    db.session.commit()


# ─── Inquiry System (investor/partner/license) ─────────────
@marketplace_bp.route("/inquire/<int:listing_id>", methods=["POST"])
@login_required
@csrf.exempt
def inquire(listing_id):
    listing = MarketplaceListing.query.get_or_404(listing_id)
    if listing.user_id == current_user.id:
        return jsonify({"error": "لا يمكنك إرسال استفسار لدراستك"}), 400

    existing = MarketplaceInquiry.query.filter_by(
        listing_id=listing_id, sender_id=current_user.id
    ).first()
    if existing:
        return jsonify({"error": "لقد أرسلت استفساراً مسبقاً لهذه الدراسة"}), 400

    data = request.get_json(silent=True) or {}
    inquiry_type_map = {
        "find_investor": "invest",
        "find_partner": "partner",
        "license": "license",
    }
    inquiry = MarketplaceInquiry(
        listing_id=listing_id,
        sender_id=current_user.id,
        inquiry_type=inquiry_type_map.get(listing.listing_goal, "general"),
        message=data.get("message", "").strip() or "أنا مهتم بهذه الدراسة",
        contact_info=data.get("contact_info", "").strip(),
    )
    db.session.add(inquiry)

    # Notify listing owner
    notif = Notification(
        user_id=listing.user_id,
        title="استفسار جديد عن دراستك",
        message=f"أبدى {current_user.name} اهتمامه بدراسة «{listing.title}».",
        category="marketplace",
        link=url_for("marketplace.my_inquiries"),
    )
    db.session.add(notif)
    db.session.commit()

    return jsonify({"status": "ok", "message": "تم إرسال طلبك بنجاح"})


@marketplace_bp.route("/inquiry/<int:inquiry_id>/reply", methods=["POST"])
@login_required
@csrf.exempt
def reply_inquiry(inquiry_id):
    inquiry = MarketplaceInquiry.query.get_or_404(inquiry_id)
    if inquiry.listing.user_id != current_user.id:
        return jsonify({"error": "غير مصرح"}), 403

    data = request.get_json(silent=True) or {}
    action = data.get("action", "reply")  # reply, accept, reject
    inquiry.reply_message = data.get("reply_message", "").strip()

    if action == "accept":
        inquiry.status = "accepted"
    elif action == "reject":
        inquiry.status = "rejected"
    else:
        inquiry.status = "replied"
    db.session.commit()

    # Notify sender
    status_labels = {"accepted": "تم قبول طلبك ✅", "rejected": "تم رفض طلبك", "replied": "رد جديد على استفسارك"}
    notif = Notification(
        user_id=inquiry.sender_id,
        title=status_labels.get(inquiry.status, "تحديث على استفسارك"),
        message=f"رد صاحب دراسة «{inquiry.listing.title}» على استفسارك.",
        category="marketplace",
        link=url_for("marketplace.view_listing", listing_id=inquiry.listing_id),
    )
    db.session.add(notif)
    db.session.commit()

    return jsonify({"status": "ok"})


@marketplace_bp.route("/inquiry/<int:inquiry_id>/add-to-crm", methods=["POST"])
@login_required
@csrf.exempt
def add_inquiry_to_crm(inquiry_id):
    """Add accepted investor inquiry to Investor CRM."""
    inquiry = MarketplaceInquiry.query.get_or_404(inquiry_id)
    if inquiry.listing.user_id != current_user.id:
        return jsonify({"error": "غير مصرح"}), 403

    from app.models.features import InvestorContact
    contact = InvestorContact(
        user_id=current_user.id,
        report_id=inquiry.listing.report_id,
        name=inquiry.sender.name,
        email=inquiry.sender.email,
        stage="contacted",
        notes=f"من سوق الدراسات — {inquiry.message}",
    )
    db.session.add(contact)
    db.session.commit()
    return jsonify({"status": "ok", "message": "تمت الإضافة لإدارة المستثمرين"})


# ─── Reviews ────────────────────────────────────────────────
@marketplace_bp.route("/review/<int:purchase_id>", methods=["POST"])
@login_required
@csrf.exempt
def add_review(purchase_id):
    purchase_record = MarketplacePurchase.query.get_or_404(purchase_id)
    if purchase_record.buyer_id != current_user.id:
        return jsonify({"error": "غير مصرح"}), 403
    if purchase_record.status != "completed":
        return jsonify({"error": "لم يكتمل الشراء بعد"}), 400

    existing = MarketplaceReview.query.filter_by(purchase_id=purchase_id).first()
    if existing:
        return jsonify({"error": "لقد قيّمت هذه الدراسة مسبقاً"}), 400

    data = request.get_json(silent=True) or {}
    rating = data.get("rating", 5)
    try:
        rating = max(1, min(5, int(rating)))
    except (ValueError, TypeError):
        rating = 5

    review = MarketplaceReview(
        listing_id=purchase_record.listing_id,
        purchase_id=purchase_id,
        buyer_id=current_user.id,
        rating=rating,
        comment=data.get("comment", "").strip(),
    )
    db.session.add(review)
    db.session.commit()
    return jsonify({"status": "ok"})


# ─── My Listings ────────────────────────────────────────────
@marketplace_bp.route("/my-listings")
@login_required
def my_listings():
    listings = MarketplaceListing.query.filter_by(user_id=current_user.id).order_by(
        MarketplaceListing.created_at.desc()).all()
    total_revenue = sum(
        p.amount for l in listings
        for p in l.purchases_list if p.status == "completed"
    )
    total_inquiries = sum(len(l.inquiries) for l in listings)
    return render_template("marketplace/my_listings.html",
        listings=listings, total_revenue=total_revenue, total_inquiries=total_inquiries,
        goal_info=GOAL_INFO)


# ─── My Purchases ──────────────────────────────────────────
@marketplace_bp.route("/my-purchases")
@login_required
def my_purchases():
    purchases = MarketplacePurchase.query.filter_by(
        buyer_id=current_user.id, status="completed"
    ).order_by(MarketplacePurchase.created_at.desc()).all()
    return render_template("marketplace/my_purchases.html", purchases=purchases)


# ─── My Inquiries (received) ───────────────────────────────
@marketplace_bp.route("/my-inquiries")
@login_required
def my_inquiries():
    inquiries = MarketplaceInquiry.query.join(MarketplaceListing).filter(
        MarketplaceListing.user_id == current_user.id
    ).order_by(MarketplaceInquiry.created_at.desc()).all()
    # Mark new ones as read
    for inq in inquiries:
        if inq.status == "new":
            inq.status = "read"
    db.session.commit()
    return render_template("marketplace/my_inquiries.html", inquiries=inquiries, goal_info=GOAL_INFO)


# ─── Edit / Withdraw Listing ───────────────────────────────
@marketplace_bp.route("/edit/<int:listing_id>", methods=["POST"])
@login_required
@csrf.exempt
def edit_listing(listing_id):
    listing = MarketplaceListing.query.get_or_404(listing_id)
    if listing.user_id != current_user.id:
        return jsonify({"error": "غير مصرح"}), 403

    data = request.get_json(silent=True) or {}
    action = data.get("action")

    if action == "withdraw":
        listing.is_active = False
        listing.approval_status = "pending"
        db.session.commit()
        return jsonify({"status": "ok", "message": "تم سحب الدراسة من السوق"})

    if action == "update_price":
        new_price = data.get("price", 0)
        try:
            listing.price = max(0, float(new_price))
        except (ValueError, TypeError):
            pass
        db.session.commit()
        return jsonify({"status": "ok"})

    return jsonify({"error": "إجراء غير معروف"}), 400


# ─── AI Auto-Fill Listing ─────────────────────────────────
@marketplace_bp.route("/api/ai-fill", methods=["POST"])
@login_required
@csrf.exempt
def api_ai_fill():
    import json as _json
    from app.ai.diamond import call_ai, run_sync
    data = request.get_json() or {}
    report_id = data.get("report_id")
    goal = data.get("goal", "sell")
    report = Report.query.get_or_404(report_id)
    if report.user_id != current_user.id:
        return jsonify({"error": "غير مصرح"}), 403

    synthesis = report.synthesis_result or {}
    sectors_list = ", ".join(SA_SECTORS)
    prompt = f"""بناءً على بيانات دراسة الجدوى التالية، أنشئ بيانات عرض سوق جذابة.

اسم المشروع: {report.project_name}
الوصف: {report.project_description}
الملخص التنفيذي: {synthesis.get('executive_summary', '')[:500]}
هدف العرض: {goal}
القطاعات المتاحة: {sectors_list}

أرجع JSON فقط:
{{
  "title": "عنوان جذاب للعرض",
  "description": "وصف تفصيلي شامل",
  "preview_text": "ملخص قصير يظهر في بطاقة العرض",
  "sector": "القطاع الأنسب من القائمة",
  "price": 0,
  "investment_needed": 0,
  "equity_offered": 0,
  "partner_role": "",
  "license_terms": ""
}}
اجعل العنوان والوصف جذابين ومهنيين. السعر بالريال السعودي."""

    try:
        messages = [
            {"role": "system", "content": "أنت خبير تسويق. أرجع JSON فقط."},
            {"role": "user", "content": prompt},
        ]
        result = run_sync(call_ai(messages, model_type="fast"))
        result_clean = result.strip()
        if result_clean.startswith("```"):
            result_clean = result_clean.split("\n", 1)[-1].rsplit("```", 1)[0].strip()
        return jsonify(_json.loads(result_clean))
    except Exception as e:
        return jsonify({"error": str(e)}), 500
