const express = require("express"); const router = express.Router(); const PeopleInfo = require("../models/peopleInfo"); router.get("/people_info", async (req, res) => { try { const { searchfield, value } = req.query; if (!searchfield || !value) { return res.status(400).json({ message: "searchfield and value parameters are required", }); } let matchQuery = {}; if (searchfield === "mobile") { let normalizedSearch = value.replace(/\D/g, ""); const withLeadingZero = normalizedSearch.startsWith("0") ? normalizedSearch : `0${normalizedSearch}`; const withoutLeadingZero = normalizedSearch.startsWith("0") ? normalizedSearch.substring(1) : normalizedSearch; const numericValue = parseInt(withoutLeadingZero, 10); matchQuery = { $or: [ { mobile: withLeadingZero }, { mobile: withoutLeadingZero }, { mobile: numericValue }, ], }; } else if (searchfield === "name") { matchQuery = { $or: [ { name: { $regex: value, $options: "i" } }, { family: { $regex: value, $options: "i" } }, { $expr: { $regexMatch: { input: { $concat: ["$name", " ", "$family"] }, regex: value, options: "i", }, }, }, ], }; } else if (searchfield === "nationalcode") { matchQuery = { nationalcode: value }; } else { return res.status(400).json({ message: "Invalid searchfield. Must be 'mobile', 'name', or 'nationalcode'", }); } const pipeline = [ { $match: matchQuery }, { $limit: 10000 }, { $group: { _id: "$nationalcode", items: { $push: { name: "$name", family: "$family", mobile: "$mobile", mellicard: "$mellicard", mellatcard: "$mellatcard", father: "$father", birthdate: "$birthdate", info1: "$info1", info2: "$info2", info3: "$info3", info4: "$info4", hasMellatcard: { $cond: [{ $ne: ["$mellatcard", null] }, true, false], }, hasMellicard: { $cond: [{ $ne: ["$mellicard", null] }, true, false], }, }, }, }, }, { $project: { nationalcode: "$_id", items: 1, firstWithMellatcard: { $arrayElemAt: [ { $filter: { input: "$items", as: "item", cond: { $eq: ["$$item.hasMellatcard", true] }, }, }, 0, ], }, firstWithMellicard: { $arrayElemAt: [ { $filter: { input: "$items", as: "item", cond: { $eq: ["$$item.hasMellicard", true] }, }, }, 0, ], }, hasAnyMellatcard: { $gt: [ { $size: { $filter: { input: "$items", as: "item", cond: { $eq: ["$$item.hasMellatcard", true] }, }, }, }, 0, ], }, hasAnyMellicard: { $gt: [ { $size: { $filter: { input: "$items", as: "item", cond: { $eq: ["$$item.hasMellicard", true] }, }, }, }, 0, ], }, }, }, { $project: { nationalcode: 1, name: { $cond: [ { $ne: ["$firstWithMellatcard", null] }, "$firstWithMellatcard.name", { $cond: [ { $ne: ["$firstWithMellicard", null] }, "$firstWithMellicard.name", { $arrayElemAt: ["$items.name", 0] }, ], }, ], }, family: { $cond: [ { $ne: ["$firstWithMellatcard", null] }, "$firstWithMellatcard.family", { $cond: [ { $ne: ["$firstWithMellicard", null] }, "$firstWithMellicard.family", { $arrayElemAt: ["$items.family", 0] }, ], }, ], }, father: { $cond: [ { $ne: ["$firstWithMellatcard", null] }, "$firstWithMellatcard.father", { $cond: [ { $ne: ["$firstWithMellicard", null] }, "$firstWithMellicard.father", null, ], }, ], }, birthdate: { $cond: [ { $ne: ["$firstWithMellatcard", null] }, "$firstWithMellatcard.birthdate", { $cond: [ { $ne: ["$firstWithMellicard", null] }, "$firstWithMellicard.birthdate", null, ], }, ], }, mobile: { $filter: { input: "$items.mobile", as: "mob", cond: { $ne: ["$$mob", null] }, }, }, allCards: { $reduce: { input: "$items", initialValue: [], in: { $concatArrays: [ "$$value", { $filter: { input: ["$$this.mellatcard", "$$this.mellicard"], as: "card", cond: { $ne: ["$$card", null] }, }, }, ], }, }, }, info: { $reduce: { input: "$items", initialValue: [], in: { $concatArrays: [ "$$value", { $filter: { input: [ "$$this.info1", "$$this.info2", "$$this.info3", "$$this.info4", ], as: "inf", cond: { $ne: ["$$inf", null] }, }, }, ], }, }, }, }, }, { $project: { nationalcode: 1, name: 1, family: 1, father: 1, birthdate: 1, mobile: 1, card: "$allCards", info: 1, }, }, ]; const results = await PeopleInfo.aggregate(pipeline).allowDiskUse(true); const processedResults = results.map((result) => { const mobileSet = new Set(); result.mobile.forEach((mob) => { if (mob == null) return; const mobStr = String(mob); const normalized = mobStr.startsWith("0") ? mobStr.substring(1) : mobStr; mobileSet.add(`0${normalized}`); }); result.mobile = Array.from(mobileSet); if (result.card) { const cardSet = new Set(); result.card.forEach((card) => { if (card && typeof card === "string") { cardSet.add(card.trim()); } }); result.card = Array.from(cardSet); } if (result.birthdate && result.birthdate instanceof Date) { result.birthdate = result.birthdate.toISOString().split("T")[0]; } result.info = result.info.map((inf) => { return typeof inf === "string" ? inf.replace(/\t/g, "") : inf; }); return result; }); res.status(200).json({ data: processedResults, count: processedResults.length, }); } catch (error) { console.error("Error fetching people info:", error); res .status(500) .json({ message: "Internal Server Error", error: error.message }); } }); router.post("/people_info", async (req, res) => { try { const { first_name, last_name, mobile, postal, province, city, nationalcode, } = req.body; const newPeopleInfo = new PeopleInfo({ first_name, last_name, mobile, postal, province, city, nationalcode, }); await newPeopleInfo.save(); res.status(201).json({ message: "People info created successfully", data: newPeopleInfo, }); } catch (error) { console.error("Error creating people info:", error); res .status(500) .json({ message: "Internal Server Error", error: error.message }); } }); module.exports = router;