from datetime import timedelta

from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.core.exceptions import ValidationError
from django.forms import formset_factory
from django.db import transaction
from django.db.models import Count, Q, Sum
from django.http import HttpResponseForbidden
from django.shortcuts import get_object_or_404, redirect, render
from django.urls import reverse
from django.utils import timezone
from django.views.decorators.http import require_http_methods

from contract.models import User
from contract.utils.auth_helpers import format_phone_number
from contract.utils.sys_settings import get_system_setting
from market.forms import CompanyInvitationForm, CompanyProductForm, CompanyProfileForm, CompanyRFQResponseForm
from market.models import (
    CompanyActivityLog,
    CompanyDocument,
    CompanyInvitation,
    CompanyMember,
    CompanyProductRFQ,
    CompanyProfile,
    MarketOrder,
    MarketProduct,
)
from market.services.access import (
    can_manage_company,
    can_manage_company_products,
    can_manage_company_rfqs,
    can_manage_company_team,
    can_submit_company_products,
    can_view_company_reports,
    get_company_membership,
    resolve_company_for_user,
    user_company_role,
)
from market.services.company_notifications import (
    notify_company_member_added,
    notify_company_member_role_changed,
    notify_company_member_status_changed,
    notify_company_product_submitted,
    notify_company_rfq_event,
    notify_company_status_changed,
)
from market.views.helpers import build_market_context


CompanyInviteFormSet = formset_factory(CompanyInvitationForm, extra=3, max_num=5)


def _company_product_has_paid_hosting_fee(product):
    if not product:
        return False
    if product.latest_paid_at:
        return True
    return product.hosting_fee_payments.filter(status="PAID").exists()


def _company_max_team_members():
    raw_value = get_system_setting("COMPANY_MAX_TEAM_MEMBERS", default="10")
    try:
        value = int(raw_value)
    except (TypeError, ValueError):
        return 0
    return max(value, 0)


def _company_team_member_usage(company):
    active_members = company.members.filter(is_active=True).count()
    pending_invitations = company.invitations.filter(status=CompanyInvitation.Status.PENDING).count()
    return active_members + pending_invitations


def _enforce_company_team_limit(company, *, actor):
    if getattr(actor, "is_superuser", False):
        return

    max_members = _company_max_team_members()
    if not max_members:
        return

    if _company_team_member_usage(company) >= max_members:
        raise ValidationError(
            (
                f"This company has reached the maximum team size of {max_members}. "
                "Ask a platform administrator to raise the limit or deactivate an existing member."
            )
        )


def _find_user_by_contact(email: str | None = None, phone_number: str | None = None):
    if email:
        user = User.objects.filter(email__iexact=email).first()
        if user:
            return user
    if phone_number:
        normalized_phone = format_phone_number(phone_number)
        if normalized_phone:
            user = User.objects.filter(phone_number=normalized_phone).first()
            if user:
                return user
    return None


def _upsert_company_member(company, *, actor, email: str = "", phone_number: str = "", display_name: str = "", member_role: str = CompanyMember.Roles.SALESPERSON):
    _enforce_company_team_limit(company, actor=actor)
    existing_user = _find_user_by_contact(email=email, phone_number=phone_number)
    if existing_user:
        membership, created = CompanyMember.objects.get_or_create(
            company=company,
            user=existing_user,
            defaults={
                "member_role": member_role,
                "invited_by": actor,
                "joined_at": timezone.now(),
                "is_active": True,
            },
        )
        if not created:
            updates = []
            if membership.member_role != member_role:
                membership.member_role = member_role
                updates.append("member_role")
            if not membership.is_active:
                membership.is_active = True
                updates.append("is_active")
            membership.deactivated_at = None
            membership.deactivated_by = None
            membership.joined_at = membership.joined_at or timezone.now()
            updates.extend(["deactivated_at", "deactivated_by", "joined_at"])
            updates = list(dict.fromkeys(updates))
            if updates:
                membership.save(update_fields=updates)
        CompanyActivityLog.objects.create(
            company=company,
            action=CompanyActivityLog.ActionChoices.MEMBER_JOINED,
            actor=actor,
            target_user=existing_user,
            entity_type="CompanyMember",
            entity_id=str(membership.pk),
            notes=f"{existing_user.get_full_name() or existing_user.email or existing_user.phone_number} joined as {member_role}.",
        )
        notify_company_member_added(company=company, member=membership, actor=actor)
        return {"kind": "membership", "membership": membership, "user": existing_user}

    invitation, created = CompanyInvitation.objects.get_or_create(
        company=company,
        email=email or "",
        phone_number=phone_number or "",
        status=CompanyInvitation.Status.PENDING,
        defaults={
            "display_name": display_name or "",
            "member_role": member_role,
            "invited_by": actor,
            "expires_at": timezone.now() + timedelta(days=14),
        },
    )
    if not created:
        invitation.display_name = display_name or invitation.display_name
        invitation.member_role = member_role
        invitation.invited_by = actor
        invitation.expires_at = invitation.expires_at or (timezone.now() + timedelta(days=14))
        invitation.save(update_fields=["display_name", "member_role", "invited_by", "expires_at", "updated_at"])
    CompanyActivityLog.objects.create(
        company=company,
        action=CompanyActivityLog.ActionChoices.INVITED_MEMBER,
        actor=actor,
        entity_type="CompanyInvitation",
        entity_id=str(invitation.pk),
        notes=f"Invitation queued for {email or phone_number or display_name or 'salesperson'}.",
    )
    return {"kind": "invitation", "invitation": invitation}


def _company_member_label(user):
    if not user:
        return ""
    return user.get_full_name() or user.email or user.phone_number or str(user.pk)


def _status_count_rows(choices, counts):
    rows = []
    total = sum(int(value or 0) for value in counts.values()) or 0
    for value, label in choices:
        count = int(counts.get(value, 0) or 0)
        rows.append(
            {
                "value": value,
                "label": label,
                "count": count,
                "percent": round((count / total) * 100) if total else 0,
            }
        )
    return rows


def _company_ops_context(request, company, membership, *, active="overview"):
    role = membership.member_role if membership else "SUPERUSER"
    products = company.products.all()
    rfqs = company.product_rfqs.all()
    orders = MarketOrder.objects.filter(seller_orders__items__product__company=company).distinct()
    if membership and membership.member_role == CompanyMember.Roles.SALESPERSON:
        products = products.filter(Q(created_by=membership.user) | Q(managed_by=membership.user))
        rfqs = rfqs.filter(Q(assigned_to=membership.user) | Q(product__created_by=membership.user))
        orders = orders.filter(seller_orders__items__product__created_by=membership.user).distinct()

    product_counts = {row["status"]: row["total"] for row in products.values("status").annotate(total=Count("id"))}
    rfq_counts = {row["status"]: row["total"] for row in rfqs.values("status").annotate(total=Count("id"))}
    documents = company.documents.all()
    required_doc_types = [
        CompanyDocument.DocumentTypes.REGISTRATION_CERTIFICATE,
        CompanyDocument.DocumentTypes.TAX_PIN,
        CompanyDocument.DocumentTypes.BUSINESS_LICENSE,
    ]
    uploaded_doc_types = set(documents.values_list("document_type", flat=True))
    missing_doc_types = [doc_type for doc_type in required_doc_types if doc_type not in uploaded_doc_types]
    verified_docs = documents.filter(is_verified=True).count()
    pending_docs = documents.filter(is_verified=False).count()
    compliance_total = len(required_doc_types)
    compliance_score = round(((compliance_total - len(missing_doc_types)) / compliance_total) * 100) if compliance_total else 0
    order_summary = orders.aggregate(order_count=Count("id", distinct=True), revenue=Sum("grand_total"))

    nav = [
        {"key": "overview", "label": "Overview", "icon": "fa-gauge-high", "href": reverse("market:company_workspace")},
        {"key": "team", "label": "Team", "icon": "fa-users", "href": reverse("market:company_team")},
        {"key": "products", "label": "Products", "icon": "fa-boxes-stacked", "href": reverse("market:company_products")},
        {"key": "rfqs", "label": "RFQs / Offers", "icon": "fa-comments-dollar", "href": reverse("market:company_rfqs")},
        {"key": "reports", "label": "Reports", "icon": "fa-chart-line", "href": reverse("market:company_reports")},
        {"key": "compliance", "label": "Compliance", "icon": "fa-shield-halved", "href": f"{reverse('market:company_workspace')}#company-compliance"},
        {"key": "activity", "label": "Activity", "icon": "fa-timeline", "href": f"{reverse('market:company_workspace')}#company-activity"},
        {"key": "settings", "label": "Settings", "icon": "fa-sliders", "href": f"{reverse('market:company_workspace')}#company-settings"},
    ]
    if role in {CompanyMember.Roles.VIEWER, CompanyMember.Roles.APPROVER}:
        nav = [item for item in nav if item["key"] not in {"settings"}]

    return {
        "active": active,
        "role": role,
        "role_label": membership.get_member_role_display() if membership else "Superuser",
        "nav": nav,
        "can_manage_team": can_manage_company_team(request.user, company=company) or request.user.is_superuser,
        "can_create_products": company.can_publish_products and (can_manage_company_products(request.user, company=company) or request.user.is_superuser),
        "can_manage_products": can_manage_company_products(request.user, company=company) or request.user.is_superuser,
        "can_manage_rfqs": can_manage_company_rfqs(request.user, company=company) or request.user.is_superuser,
        "team_count": company.members.count(),
        "active_team_count": company.members.filter(is_active=True).count(),
        "active_salesperson_count": company.members.filter(is_active=True, member_role=CompanyMember.Roles.SALESPERSON).count(),
        "pending_invite_count": company.invitations.filter(status=CompanyInvitation.Status.PENDING).count(),
        "product_count": products.count(),
        "active_product_count": products.filter(is_active=True, status=MarketProduct.Status.APPROVED).count(),
        "pending_product_count": int(product_counts.get(MarketProduct.Status.PENDING_APPROVAL, 0) or 0)
        + int(product_counts.get(MarketProduct.Status.SUBMITTED, 0) or 0),
        "open_rfq_count": int(rfq_counts.get(CompanyProductRFQ.Status.OPEN, 0) or 0),
        "rfq_count": rfqs.count(),
        "order_count": int(order_summary.get("order_count") or 0),
        "revenue_total": int(order_summary.get("revenue") or 0),
        "product_pipeline": _status_count_rows(MarketProduct.Status.choices, product_counts),
        "rfq_pipeline": _status_count_rows(CompanyProductRFQ.Status.choices, rfq_counts),
        "document_count": documents.count(),
        "verified_document_count": verified_docs,
        "pending_document_count": pending_docs,
        "missing_document_count": len(missing_doc_types),
        "missing_document_types": missing_doc_types,
        "compliance_score": compliance_score,
        "recent_activity": (
            CompanyActivityLog.objects.select_related("actor", "target_user")
            .filter(company=company)
            .order_by("-created_at", "-id")[:10]
        ),
    }


def _company_workspace_or_403(request, company_id=None):
    company = get_object_or_404(CompanyProfile, pk=company_id) if company_id else resolve_company_for_user(request.user)
    if not company:
        messages.info(request, "Create a company profile to access the company workspace.")
        return None, None, redirect("market:company_register")
    membership = get_company_membership(request.user, company=company)
    if not membership and not request.user.is_superuser:
        return company, membership, HttpResponseForbidden("You do not have access to this company workspace.")
    return company, membership, None


def _company_reports_payload(company, membership):
    role = membership.member_role if membership else "SUPERUSER"
    products = MarketProduct.objects.filter(company=company)
    rfqs = CompanyProductRFQ.objects.filter(company=company)
    orders = MarketOrder.objects.filter(seller_orders__items__product__company=company).distinct()
    if role == CompanyMember.Roles.SALESPERSON:
        products = products.filter(Q(created_by=membership.user) | Q(managed_by=membership.user))
        rfqs = rfqs.filter(Q(assigned_to=membership.user) | Q(product__created_by=membership.user))
        orders = orders.filter(seller_orders__items__product__created_by=membership.user).distinct()

    product_counts = {row["status"]: row["total"] for row in products.values("status").annotate(total=Count("id"))}
    rfq_counts = {row["status"]: row["total"] for row in rfqs.values("status").annotate(total=Count("id"))}
    order_summary = orders.aggregate(order_count=Count("id", distinct=True), revenue=Sum("grand_total"))
    salesperson_rows = []
    if role in {CompanyMember.Roles.OWNER, CompanyMember.Roles.ADMIN, CompanyMember.Roles.MANAGER, "SUPERUSER"}:
        for member in company.members.select_related("user").filter(is_active=True).order_by("member_role", "user__first_name"):
            salesperson_rows.append(
                {
                    "member": member,
                    "product_count": company.products.filter(Q(created_by=member.user) | Q(managed_by=member.user)).distinct().count(),
                    "rfq_count": company.product_rfqs.filter(Q(assigned_to=member.user) | Q(product__created_by=member.user)).distinct().count(),
                    "order_count": MarketOrder.objects.filter(seller_orders__items__product__company=company, seller_orders__items__product__created_by=member.user).distinct().count(),
                }
            )
    return {
        "products": products.order_by("-updated_at", "-id"),
        "rfqs": rfqs.select_related("product", "buyer", "assigned_to").order_by("-updated_at", "-id"),
        "orders": orders.order_by("-created_at", "-id"),
        "product_counts": product_counts,
        "rfq_counts": rfq_counts,
        "order_count": int(order_summary.get("order_count") or 0),
        "revenue_total": int(order_summary.get("revenue") or 0),
        "salesperson_rows": salesperson_rows,
    }


@login_required(login_url="market:login")
@require_http_methods(["GET", "POST"])
def company_register(request):
    existing_company = resolve_company_for_user(request.user)
    if existing_company:
        messages.info(request, "You already have a company workspace.")
        return redirect("market:company_workspace")

    profile_form = CompanyProfileForm(request.POST or None, user=request.user)
    invite_forms = CompanyInviteFormSet(request.POST or None, prefix="invites")

    if request.method == "POST" and profile_form.is_valid() and invite_forms.is_valid():
        with transaction.atomic():
            company = profile_form.save(commit=False)
            company.created_by = request.user
            company.submitted_at = timezone.now()
            company.save()

            CompanyMember.objects.create(
                company=company,
                user=request.user,
                member_role=CompanyMember.Roles.OWNER,
                invited_by=request.user,
                joined_at=timezone.now(),
                is_active=True,
            )
            CompanyActivityLog.objects.create(
                company=company,
                action=CompanyActivityLog.ActionChoices.CREATED,
                actor=request.user,
                entity_type="CompanyProfile",
                entity_id=str(company.pk),
                notes="Company profile created from the web registration flow.",
            )

            for invite_form in invite_forms:
                if not invite_form.cleaned_data:
                    continue
                if invite_form.cleaned_data.get("DELETE"):
                    continue
                email = invite_form.cleaned_data.get("email") or ""
                phone_number = invite_form.cleaned_data.get("phone_number") or ""
                display_name = invite_form.cleaned_data.get("display_name") or ""
                member_role = invite_form.cleaned_data.get("member_role") or CompanyMember.Roles.SALESPERSON
                if email or phone_number:
                    _upsert_company_member(
                        company,
                        actor=request.user,
                        email=email,
                        phone_number=phone_number,
                        display_name=display_name,
                        member_role=member_role,
                    )

            notify_company_status_changed(
                company=company,
                status_label="created and pending review",
                actor=request.user,
            )

        messages.success(request, "Your company profile has been created.")
        return redirect("market:company_workspace")

    context = build_market_context(
        request,
        form=profile_form,
        invite_formset=invite_forms,
    )
    return render(request, "market/companies/register.html", context)


@login_required(login_url="market:login")
def company_workspace(request, company_id=None):
    company = None
    if company_id:
        company = get_object_or_404(CompanyProfile.objects.select_related("legacy_seller_profile", "reviewed_by"), pk=company_id)
    else:
        company = resolve_company_for_user(request.user)

    if not company:
        messages.info(request, "Create a company profile to access the company workspace.")
        return redirect("market:company_register")

    membership = get_company_membership(request.user, company=company)
    if not membership and not request.user.is_superuser:
        return HttpResponseForbidden("You do not have access to this company workspace.")

    if request.method == "POST":
        action = (request.POST.get("action") or "").strip()
        if action == "invite_member" and (can_manage_company_team(request.user, company=company) or request.user.is_superuser):
            invite_form = CompanyInvitationForm(request.POST)
            if invite_form.is_valid():
                try:
                    with transaction.atomic():
                        _upsert_company_member(
                            company,
                            actor=request.user,
                            email=invite_form.cleaned_data.get("email") or "",
                            phone_number=invite_form.cleaned_data.get("phone_number") or "",
                            display_name=invite_form.cleaned_data.get("display_name") or "",
                            member_role=invite_form.cleaned_data.get("member_role") or CompanyMember.Roles.SALESPERSON,
                        )
                except ValidationError as exc:
                    messages.error(request, "; ".join(exc.messages))
                else:
                    messages.success(request, "Member invitation updated.")
                    return redirect("market:company_workspace")
        elif action == "remove_member" and (can_manage_company_team(request.user, company=company) or request.user.is_superuser):
            member_id = request.POST.get("member_id")
            member = get_object_or_404(CompanyMember, pk=member_id, company=company)
            if member.is_owner:
                messages.error(request, "Company owners cannot be removed from the workspace.")
            else:
                member.is_active = False
                member.deactivated_by = request.user
                member.deactivated_at = timezone.now()
                member.save(update_fields=["is_active", "deactivated_by", "deactivated_at", "updated_at"])
                CompanyActivityLog.objects.create(
                    company=company,
                    action=CompanyActivityLog.ActionChoices.MEMBER_REMOVED,
                    actor=request.user,
                    target_user=member.user,
                    entity_type="CompanyMember",
                    entity_id=str(member.pk),
                    notes=f"Removed {member.user.get_full_name() or member.user.email or member.user.phone_number} from the company.",
                )
                messages.success(request, "Member removed from the company.")
                return redirect("market:company_workspace")

    members = company.members.select_related("user", "invited_by", "deactivated_by").order_by("-is_active", "member_role", "user__first_name", "user__last_name")
    invitations = company.invitations.select_related("invited_by", "accepted_by").order_by("-created_at")
    active_member_count = members.filter(is_active=True).count()
    pending_invite_count = invitations.filter(status=CompanyInvitation.Status.PENDING).count()
    member_count = members.count()
    active_product_count = company.products.filter(is_active=True).count()
    recent_activity = list(
        CompanyActivityLog.objects.select_related("actor", "target_user")
        .filter(company=company)
        .order_by("-created_at", "-id")[:8]
    )
    add_member_form = CompanyInvitationForm()
    if membership and membership.member_role == CompanyMember.Roles.VIEWER:
        add_member_form = None
    company_role_label = membership.get_member_role_display() if membership else "Superuser"

    context = build_market_context(
        request,
        company=company,
        company_ops=_company_ops_context(request, company, membership, active="overview"),
        company_membership=membership,
        company_can_manage=can_manage_company(request.user, company=company) or request.user.is_superuser,
        company_role_label=company_role_label,
        company_members=members,
        company_invitations=invitations,
        company_member_count=member_count,
        company_active_member_count=active_member_count,
        company_pending_invite_count=pending_invite_count,
        company_product_count=company.products.count(),
        company_active_product_count=active_product_count,
        company_recent_activity=recent_activity,
        add_member_form=add_member_form,
    )
    return render(request, "market/companies/workspace.html", context)


@login_required(login_url="market:login")
def company_team(request, company_id=None):
    company, membership, response = _company_workspace_or_403(request, company_id=company_id)
    if response:
        return response
    can_manage_team = can_manage_company_team(request.user, company=company) or request.user.is_superuser

    if request.method == "POST":
        if not can_manage_team:
            messages.error(request, "Only company owners, admins, and managers can manage team members.")
            return redirect("market:company_team")
        action = (request.POST.get("action") or "").strip()
        member = None
        member_id = request.POST.get("member_id")
        if member_id:
            member = get_object_or_404(CompanyMember, pk=member_id, company=company)
        if action == "add_member":
            invite_form = CompanyInvitationForm(request.POST)
            if invite_form.is_valid():
                try:
                    with transaction.atomic():
                        _upsert_company_member(
                            company,
                            actor=request.user,
                            email=invite_form.cleaned_data.get("email") or "",
                            phone_number=invite_form.cleaned_data.get("phone_number") or "",
                            display_name=invite_form.cleaned_data.get("display_name") or "",
                            member_role=invite_form.cleaned_data.get("member_role") or CompanyMember.Roles.SALESPERSON,
                        )
                except ValidationError as exc:
                    messages.error(request, "; ".join(exc.messages))
                else:
                    messages.success(request, "Team member or invitation saved.")
                    return redirect("market:company_team")
        elif action == "change_role" and member:
            new_role = request.POST.get("member_role")
            if new_role not in dict(CompanyMember.Roles.choices):
                messages.error(request, "Choose a valid role.")
            elif membership.member_role == CompanyMember.Roles.ADMIN and member.member_role == CompanyMember.Roles.OWNER:
                messages.error(request, "Admins cannot change an owner role.")
            else:
                old_role = member.member_role
                member.member_role = new_role
                member.save(update_fields=["member_role", "updated_at"])
                CompanyActivityLog.objects.create(
                    company=company,
                    action=CompanyActivityLog.ActionChoices.UPDATED,
                    actor=request.user,
                    target_user=member.user,
                    entity_type="CompanyMember",
                    entity_id=str(member.pk),
                    notes=f"Role changed from {old_role} to {new_role}.",
                )
                notify_company_member_role_changed(
                    company=company,
                    member=member,
                    old_role=old_role,
                    actor=request.user,
                )
                messages.success(request, "Member role updated.")
                return redirect("market:company_team")
        elif action in {"deactivate", "reactivate", "remove"} and member:
            if membership.member_role == CompanyMember.Roles.ADMIN and member.member_role == CompanyMember.Roles.OWNER:
                messages.error(request, "Admins cannot remove or deactivate owners.")
            elif member.member_role in {CompanyMember.Roles.OWNER, CompanyMember.Roles.ADMIN} and member.is_active and action in {"deactivate", "remove"} and company.members.filter(is_active=True, member_role__in=[CompanyMember.Roles.OWNER, CompanyMember.Roles.ADMIN]).exclude(pk=member.pk).count() == 0:
                messages.error(request, "A company must always have at least one active owner or admin.")
            elif action == "reactivate":
                member.is_active = True
                member.deactivated_by = None
                member.deactivated_at = None
                member.save(update_fields=["is_active", "deactivated_by", "deactivated_at", "updated_at"])
                log_action = CompanyActivityLog.ActionChoices.MEMBER_JOINED
                messages.success(request, "Member reactivated.")
            else:
                member.is_active = False
                member.deactivated_by = request.user
                member.deactivated_at = timezone.now()
                member.save(update_fields=["is_active", "deactivated_by", "deactivated_at", "updated_at"])
                log_action = CompanyActivityLog.ActionChoices.MEMBER_REMOVED
                messages.success(request, "Member deactivated.")
            if action in {"deactivate", "reactivate", "remove"} and "log_action" in locals():
                CompanyActivityLog.objects.create(
                    company=company,
                    action=log_action,
                    actor=request.user,
                    target_user=member.user,
                    entity_type="CompanyMember",
                    entity_id=str(member.pk),
                    notes=f"{action.title()} member {_company_member_label(member.user)}.",
                )
                notify_company_member_status_changed(
                    company=company,
                    member=member,
                    is_active=member.is_active,
                    actor=request.user,
                )
                return redirect("market:company_team")

    report = _company_reports_payload(company, membership)
    return render(
        request,
        "market/companies/team.html",
        build_market_context(
            request,
            company=company,
            company_ops=_company_ops_context(request, company, membership, active="team"),
            company_membership=membership,
            company_can_manage_team=can_manage_team,
            company_members=company.members.select_related("user", "invited_by", "deactivated_by").order_by("-is_active", "member_role", "user__first_name"),
            company_invitations=company.invitations.select_related("invited_by").order_by("-created_at"),
            member_role_choices=CompanyMember.Roles.choices,
            salesperson_rows=report["salesperson_rows"],
        ),
    )


@login_required(login_url="market:login")
def company_team_add(request, company_id=None):
    company, membership, response = _company_workspace_or_403(request, company_id=company_id)
    if response:
        return response
    if not (can_manage_company_team(request.user, company=company) or request.user.is_superuser):
        messages.error(request, "Only company owners, admins, and managers can add team members.")
        return redirect("market:company_team")

    form = CompanyInvitationForm(request.POST or None)
    if request.method == "POST" and form.is_valid():
        try:
            with transaction.atomic():
                _upsert_company_member(
                    company,
                    actor=request.user,
                    email=form.cleaned_data.get("email") or "",
                    phone_number=form.cleaned_data.get("phone_number") or "",
                    display_name=form.cleaned_data.get("display_name") or "",
                    member_role=form.cleaned_data.get("member_role") or CompanyMember.Roles.SALESPERSON,
                )
        except ValidationError as exc:
            messages.error(request, "; ".join(exc.messages))
        else:
            messages.success(request, "Team member or invitation saved.")
            return redirect("market:company_team")

    return render(
        request,
        "market/companies/team_form.html",
        build_market_context(
            request,
            company=company,
            company_ops=_company_ops_context(request, company, membership, active="team"),
            company_membership=membership,
            form=form,
            form_title="Add team member",
            form_subtitle="Create access for an existing user or queue a clean invitation.",
            cancel_url=reverse("market:company_team"),
            mode="add",
        ),
    )


@login_required(login_url="market:login")
def company_team_member_edit(request, member_id, company_id=None):
    company, membership, response = _company_workspace_or_403(request, company_id=company_id)
    if response:
        return response
    if not (can_manage_company_team(request.user, company=company) or request.user.is_superuser):
        messages.error(request, "Only company owners, admins, and managers can edit team members.")
        return redirect("market:company_team")

    member = get_object_or_404(CompanyMember.objects.select_related("user"), pk=member_id, company=company)
    if request.method == "POST":
        action = (request.POST.get("action") or "").strip()
        if membership and membership.member_role == CompanyMember.Roles.ADMIN and member.member_role == CompanyMember.Roles.OWNER:
            messages.error(request, "Admins cannot update company owners.")
        elif action == "update_member":
            user = member.user
            first_name = (request.POST.get("first_name") or "").strip()
            last_name = (request.POST.get("last_name") or "").strip()
            email = (request.POST.get("email") or "").strip().lower()
            raw_phone = (request.POST.get("phone_number") or "").strip()
            phone_number = format_phone_number(raw_phone) if raw_phone else ""
            new_role = request.POST.get("member_role")
            if new_role not in dict(CompanyMember.Roles.choices):
                messages.error(request, "Choose a valid role.")
            elif email and User.objects.filter(email__iexact=email).exclude(pk=user.pk).exists():
                messages.error(request, "This email is already used by another account.")
            elif raw_phone and not phone_number:
                messages.error(request, "Enter a valid Kenyan phone number.")
            elif phone_number and User.objects.filter(phone_number=phone_number).exclude(pk=user.pk).exists():
                messages.error(request, "This phone number is already used by another account.")
            else:
                old_role = member.member_role
                user.first_name = first_name
                user.last_name = last_name
                if email:
                    user.email = email
                if phone_number:
                    user.phone_number = phone_number
                user.save(update_fields=["first_name", "last_name", "email", "phone_number"])
                member.member_role = new_role
                member.save(update_fields=["member_role", "updated_at"])
                if old_role != new_role:
                    notify_company_member_role_changed(company=company, member=member, old_role=old_role, actor=request.user)
                messages.success(request, "Member details updated.")
                return redirect("market:company_team")
        elif action == "change_role":
            new_role = request.POST.get("member_role")
            if new_role not in dict(CompanyMember.Roles.choices):
                messages.error(request, "Choose a valid role.")
            else:
                old_role = member.member_role
                member.member_role = new_role
                member.save(update_fields=["member_role", "updated_at"])
                notify_company_member_role_changed(company=company, member=member, old_role=old_role, actor=request.user)
                messages.success(request, "Member role updated.")
                return redirect("market:company_team")
        elif action in {"deactivate", "reactivate", "remove"}:
            if member.is_owner and action == "remove":
                messages.error(request, "Company owners cannot be removed.")
            elif member.member_role in {CompanyMember.Roles.OWNER, CompanyMember.Roles.ADMIN} and member.is_active and action in {"deactivate", "remove"} and company.members.filter(is_active=True, member_role__in=[CompanyMember.Roles.OWNER, CompanyMember.Roles.ADMIN]).exclude(pk=member.pk).count() == 0:
                messages.error(request, "A company must always have at least one active owner or admin.")
            else:
                member.is_active = action == "reactivate"
                member.deactivated_by = None if member.is_active else request.user
                member.deactivated_at = None if member.is_active else timezone.now()
                member.save(update_fields=["is_active", "deactivated_by", "deactivated_at", "updated_at"])
                notify_company_member_status_changed(company=company, member=member, is_active=member.is_active, actor=request.user)
                messages.success(request, "Member access updated.")
                return redirect("market:company_team")

    return render(
        request,
        "market/companies/team_form.html",
        build_market_context(
            request,
            company=company,
            company_ops=_company_ops_context(request, company, membership, active="team"),
            company_membership=membership,
            member=member,
            member_role_choices=CompanyMember.Roles.choices,
            form_title="Edit team member",
            form_subtitle="Update role and access status away from the roster.",
            cancel_url=reverse("market:company_team"),
            mode="edit",
        ),
    )


@login_required(login_url="market:login")
def company_products(request, company_id=None):
    company, membership, response = _company_workspace_or_403(request, company_id=company_id)
    if response:
        return response
    if not can_manage_company_products(request.user, company=company) and not request.user.is_superuser:
        messages.error(request, "You do not have permission to view company products.")
        return redirect("market:company_workspace")
    products = company.products.select_related("category", "created_by", "managed_by").order_by("-updated_at", "-id")
    if membership and membership.member_role == CompanyMember.Roles.SALESPERSON:
        products = products.filter(Q(created_by=request.user) | Q(managed_by=request.user))
    return render(
        request,
        "market/companies/products/list.html",
        build_market_context(
            request,
            company=company,
            company_ops=_company_ops_context(request, company, membership, active="products"),
            company_membership=membership,
            company_products=products,
            company_can_create_products=company.can_publish_products and (can_manage_company_products(request.user, company=company) or request.user.is_superuser),
        ),
    )


@login_required(login_url="market:login")
def company_product_create(request, company_id=None):
    company, membership, response = _company_workspace_or_403(request, company_id=company_id)
    if response:
        return response
    if not company.can_publish_products:
        messages.error(request, "Only approved, active companies can post products.")
        return redirect("market:company_products")
    if not can_manage_company_products(request.user, company=company) and not request.user.is_superuser:
        messages.error(request, "You do not have permission to create company products.")
        return redirect("market:company_products")

    form = CompanyProductForm(request.POST or None)
    if request.method == "POST" and form.is_valid():
        product = form.save(commit=False)
        product.company = company
        product.seller = company.legacy_seller_profile
        product.created_by = request.user
        product.updated_by = request.user
        product.managed_by = request.user
        product.status = MarketProduct.Status.DRAFT
        product.save()
        CompanyActivityLog.objects.create(
            company=company,
            action=CompanyActivityLog.ActionChoices.CREATED,
            actor=request.user,
            entity_type="MarketProduct",
            entity_id=str(product.pk),
            notes=f"Created company product {product.name}.",
        )
        messages.success(request, "Company product created.")
        return redirect("market:company_product_edit", product_id=product.pk)
    return render(
        request,
        "market/companies/products/form.html",
        build_market_context(
            request,
            company=company,
            company_ops=_company_ops_context(request, company, membership, active="products"),
            company_membership=membership,
            form=form,
            product=None,
        ),
    )


@login_required(login_url="market:login")
def company_product_edit(request, product_id):
    product = get_object_or_404(MarketProduct.objects.select_related("company", "created_by", "managed_by"), pk=product_id, company__isnull=False)
    company, membership, response = _company_workspace_or_403(request, company_id=product.company_id)
    if response:
        return response
    if not can_manage_company_products(request.user, company=company) and not request.user.is_superuser:
        messages.error(request, "You do not have permission to edit company products.")
        return redirect("market:company_products")
    if not company.can_publish_products:
        messages.error(request, "Suspended, rejected, or pending companies cannot update products.")
        return redirect("market:company_products")
    if membership and membership.member_role == CompanyMember.Roles.SALESPERSON and product.created_by_id != request.user.id and product.managed_by_id != request.user.id:
        return HttpResponseForbidden("You can only edit products assigned to you.")

    form = CompanyProductForm(request.POST or None, instance=product)
    if request.method == "POST" and form.is_valid():
        product = form.save(commit=False)
        product.updated_by = request.user
        product.managed_by = request.user
        product.save()
        CompanyActivityLog.objects.create(
            company=company,
            action=CompanyActivityLog.ActionChoices.UPDATED,
            actor=request.user,
            entity_type="MarketProduct",
            entity_id=str(product.pk),
            notes=f"Updated company product {product.name}.",
        )
        messages.success(request, "Company product updated.")
        return redirect("market:company_products")
    return render(
        request,
        "market/companies/products/form.html",
        build_market_context(
            request,
            company=company,
            company_ops=_company_ops_context(request, company, membership, active="products"),
            company_membership=membership,
            form=form,
            product=product,
        ),
    )


@login_required(login_url="market:login")
@require_http_methods(["POST"])
def company_product_submit(request, product_id):
    product = get_object_or_404(MarketProduct, pk=product_id, company__isnull=False)
    company, membership, response = _company_workspace_or_403(request, company_id=product.company_id)
    if response:
        return response
    if not can_submit_company_products(request.user, company=company) and not request.user.is_superuser:
        messages.error(request, "You do not have permission to submit products.")
        return redirect("market:company_products")
    if not company.can_publish_products:
        messages.error(request, "Suspended, rejected, or pending companies cannot submit products.")
        return redirect("market:company_products")
    if not _company_product_has_paid_hosting_fee(product):
        messages.error(request, "Pay the hosting fee before submitting this product for approval.")
        return redirect("market:company_products")
    product.status = MarketProduct.Status.SUBMITTED
    product.submitted_at = timezone.now()
    product.updated_by = request.user
    product.managed_by = request.user
    product.save(update_fields=["status", "submitted_at", "updated_by", "managed_by", "updated_at"])
    CompanyActivityLog.objects.create(
        company=company,
        action=CompanyActivityLog.ActionChoices.SUBMITTED,
        actor=request.user,
        entity_type="MarketProduct",
        entity_id=str(product.pk),
        notes=f"Submitted {product.name} for review.",
    )
    notify_company_product_submitted(company=company, product=product, actor=request.user)
    messages.success(request, "Product submitted for approval.")
    return redirect("market:company_products")


@login_required(login_url="market:login")
def company_rfqs(request, company_id=None):
    company, membership, response = _company_workspace_or_403(request, company_id=company_id)
    if response:
        return response
    if not can_manage_company_rfqs(request.user, company=company) and not request.user.is_superuser:
        messages.error(request, "You do not have permission to view company RFQs.")
        return redirect("market:company_workspace")
    rfqs = company.product_rfqs.select_related("product", "buyer", "assigned_to", "responded_by").order_by("-updated_at", "-id")
    if membership and membership.member_role == CompanyMember.Roles.SALESPERSON:
        rfqs = rfqs.filter(Q(assigned_to=request.user) | Q(product__created_by=request.user))
    return render(
        request,
        "market/companies/rfqs/list.html",
        build_market_context(
            request,
            company=company,
            company_ops=_company_ops_context(request, company, membership, active="rfqs"),
            company_membership=membership,
            company_rfqs=rfqs,
        ),
    )


@login_required(login_url="market:login")
def company_rfq_detail(request, rfq_id):
    rfq = get_object_or_404(CompanyProductRFQ.objects.select_related("company", "product", "buyer", "assigned_to"), pk=rfq_id)
    company, membership, response = _company_workspace_or_403(request, company_id=rfq.company_id)
    if response:
        return response
    if not can_manage_company_rfqs(request.user, company=company) and not request.user.is_superuser:
        messages.error(request, "You do not have permission to respond to RFQs.")
        return redirect("market:company_workspace")
    if not company.can_publish_products:
        messages.error(request, "Suspended, rejected, or pending companies cannot respond to RFQs.")
        return redirect("market:company_rfqs")
    form = CompanyRFQResponseForm(request.POST or None, instance=rfq, company=company)
    if request.method == "POST" and form.is_valid():
        requested_status = form.cleaned_data.get("status") or rfq.status
        if rfq.status in {
            CompanyProductRFQ.Status.ACCEPTED,
            CompanyProductRFQ.Status.DECLINED,
            CompanyProductRFQ.Status.CLOSED,
        } and requested_status != rfq.status:
            messages.error(request, "This RFQ is already closed and cannot be reopened.")
            return redirect("market:company_rfq_detail", rfq_id=rfq.pk)
        rfq = form.save(commit=False)
        rfq.responded_by = request.user
        rfq.responded_at = timezone.now()
        rfq.save()
        CompanyActivityLog.objects.create(
            company=company,
            action=CompanyActivityLog.ActionChoices.UPDATED,
            actor=request.user,
            target_user=rfq.buyer,
            entity_type="CompanyProductRFQ",
            entity_id=str(rfq.pk),
            notes=f"RFQ for {rfq.product.name} updated to {rfq.status}.",
        )
        notify_company_rfq_event(
            rfq=rfq,
            event_label=f"updated to {rfq.get_status_display()}",
            actor=request.user,
            target_user=rfq.buyer,
        )
        messages.success(request, "RFQ response saved.")
        return redirect("market:company_rfqs")
    return render(
        request,
        "market/companies/rfqs/detail.html",
        build_market_context(
            request,
            company=company,
            company_ops=_company_ops_context(request, company, membership, active="rfqs"),
            company_membership=membership,
            rfq=rfq,
            form=form,
        ),
    )


@login_required(login_url="market:login")
def company_reports(request, company_id=None):
    company, membership, response = _company_workspace_or_403(request, company_id=company_id)
    if response:
        return response
    if not can_view_company_reports(request.user, company=company) and not request.user.is_superuser:
        messages.error(request, "You do not have permission to view company reports.")
        return redirect("market:company_workspace")
    report = _company_reports_payload(company, membership)
    return render(
        request,
        "market/companies/reports.html",
        build_market_context(
            request,
            company=company,
            company_ops=_company_ops_context(request, company, membership, active="reports"),
            company_membership=membership,
            company_report=report,
        ),
    )
