import jwt from "jsonwebtoken";
import Member from "../../models/member.js";
import Tag from "../../models/tag.js";
import { connectDB } from "../../utils/mongoose.js";

export default defineEventHandler(async (event) => {
  await connectDB();

  // Check if user is authenticated
  const token = getCookie(event, "auth-token");
  let isAuthenticated = false;
  let currentMemberId = null;

  if (token) {
    try {
      const decoded = jwt.verify(token, useRuntimeConfig().jwtSecret);
      currentMemberId = decoded.memberId;
      isAuthenticated = true;
    } catch (err) {
      // Invalid token, treat as public
      isAuthenticated = false;
    }
  }

  const query = getQuery(event);
  const search = query.search || "";
  const circle = query.circle || "";
  const tags = query.tags ? query.tags.split(",") : [];
  const peerSupport = query.peerSupport || "";
  const topics = query.topics ? query.topics.split(",") : [];
  const craftTag = query.craftTag || "";
  const connectionTag = query.connectionTag || "";

  // Build query
  const dbQuery = {
    showInDirectory: true,
    status: "active",
  };

  // Filter by circle if specified
  if (circle) {
    dbQuery.circle = circle;
  }

  // Collect $and conditions for combining multiple filters
  const andConditions = [];

  // Filter by peer support availability (check both old and new fields)
  if (peerSupport === "true") {
    andConditions.push({
      $or: [
        { "peerSupport.enabled": true },
        { "communityConnections.offerPeerSupport": true },
      ],
    });
  }

  // Search by name or bio
  if (search) {
    // Escape special regex characters to prevent ReDoS
    const escaped = search.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
    andConditions.push({
      $or: [
        { name: { $regex: escaped, $options: "i" } },
        { bio: { $regex: escaped, $options: "i" } },
      ],
    });
  }

  // Filter by tags (search in offering.tags or lookingFor.tags)
  if (tags.length > 0) {
    andConditions.push({
      $or: [
        { "offering.tags": { $in: tags } },
        { "lookingFor.tags": { $in: tags } },
      ],
    });
  }

  // Filter by peer support topics
  if (topics.length > 0) {
    dbQuery["peerSupport.topics"] = { $in: topics };
  }

  // Filter by craft tag
  if (craftTag) {
    dbQuery.craftTags = craftTag;
  }

  // Filter by connection tag
  if (connectionTag) {
    dbQuery["communityConnections.topics.tagSlug"] = connectionTag;
  }

  // Apply combined $and conditions
  if (andConditions.length > 0) {
    dbQuery.$and = andConditions;
  }

  try {
    const members = await Member.find(dbQuery)
      .select(
        "name pronouns timeZone avatar studio bio location socialLinks offering lookingFor privacy circle peerSupport craftTags communityConnections createdAt",
      )
      .sort({ createdAt: -1 })
      .lean();

    // Filter fields based on privacy settings
    const filteredMembers = members.map((member) => {
      const privacy = member.privacy || {};
      const filtered = {
        _id: member._id,
        name: member.name,
        circle: member.circle,
        createdAt: member.createdAt,
      };

      // Helper function to check if field should be visible
      const isVisible = (field) => {
        const privacySetting = privacy[field] || "members";
        if (privacySetting === "public") return true;
        if (privacySetting === "members" && isAuthenticated) return true;
        if (privacySetting === "private") return false;
        return false;
      };

      // Add fields based on privacy settings
      if (isVisible("avatar")) filtered.avatar = member.avatar;
      if (isVisible("pronouns")) filtered.pronouns = member.pronouns;
      if (isVisible("timeZone")) filtered.timeZone = member.timeZone;
      if (isVisible("studio")) filtered.studio = member.studio;
      if (isVisible("bio")) filtered.bio = member.bio;
      if (isVisible("location")) filtered.location = member.location;
      if (isVisible("socialLinks")) filtered.socialLinks = member.socialLinks;
      if (isVisible("offering")) filtered.offering = member.offering;
      if (isVisible("lookingFor")) filtered.lookingFor = member.lookingFor;

      // Craft tags (with fallback to offering.tags for backward compat)
      if (isVisible("craftTags")) {
        filtered.craftTags = member.craftTags;
      }

      // Community connections (expose only public-safe fields)
      if (isVisible("communityConnections")) {
        filtered.communityConnections = {
          topics: member.communityConnections?.topics,
          offerPeerSupport: member.communityConnections?.offerPeerSupport,
          availability: member.communityConnections?.availability,
        };
      }

      // Peer support: expose only fields needed for matching/contact UX
      // slackUserId, slackDMChannelId, slackUsername, personalMessage are internal
      if (member.peerSupport?.enabled) {
        filtered.peerSupport = {
          enabled: true,
          skillTopics: member.peerSupport.skillTopics,
          supportTopics: member.peerSupport.supportTopics,
          availability: member.peerSupport.availability,
        };
      }

      return filtered;
    });

    // Get unique tags for filter options (from both offering and lookingFor) — backward compat
    const allTags = members
      .flatMap((m) => [
        ...(m.offering?.tags || []),
        ...(m.lookingFor?.tags || []),
      ])
      .filter((tag, index, self) => self.indexOf(tag) === index)
      .sort();

    // Get unique peer support topics
    const allTopics = members
      .filter((m) => m.peerSupport?.enabled)
      .flatMap((m) => m.peerSupport?.topics || [])
      .filter((topic, index, self) => self.indexOf(topic) === index)
      .sort();

    // Fetch predefined tags from Tag model for filter bars
    const [craftTags, cooperativeTags] = await Promise.all([
      Tag.find({ pool: "craft", active: true }).sort({ label: 1 }).lean(),
      Tag.find({ pool: "cooperative", active: true }).sort({ label: 1 }).lean(),
    ]);

    return {
      members: filteredMembers,
      totalCount: filteredMembers.length,
      filters: {
        availableSkills: allTags,
        availableTopics: allTopics,
        craftTags: craftTags.map((t) => ({ slug: t.slug, label: t.label })),
        cooperativeTags: cooperativeTags.map((t) => ({
          slug: t.slug,
          label: t.label,
        })),
      },
    };
  } catch (error) {
    console.error("Directory fetch error:", error);
    throw createError({
      statusCode: 500,
      message: "Failed to fetch member directory",
    });
  }
});
