import { z } from "zod";
import { defineApiBackedAiTool } from "@open-mercato/ai-assistant/modules/ai_assistant/lib/api-backed-tool";
import {
  createAiApiOperationRunner
} from "@open-mercato/ai-assistant/modules/ai_assistant/lib/ai-api-operation-runner";
import { findWithDecryption } from "@open-mercato/shared/lib/encryption/find";
import {
  CustomerPersonProfile
} from "../data/entities.js";
import { assertTenantScope } from "./types.js";
import {
  buildRelatedRecords,
  buildScope,
  resolveEm,
  toCustomerListSummary,
  toIso
} from "./_shared.js";
const NIL_UUID = "00000000-0000-0000-0000-000000000000";
const listPeopleInput = z.object({
  q: z.string().trim().optional().describe("Optional search text matched against display name / email / phone. Omit or leave empty to list all."),
  limit: z.number().int().min(1).max(100).optional().describe("Maximum rows to return (default 50, max 100)."),
  offset: z.number().int().min(0).optional().describe("Number of rows to skip (default 0)."),
  tags: z.array(z.string().uuid()).optional().describe("Restrict to persons carrying at least one of these tag ids."),
  companyId: z.string().uuid().optional().describe("Restrict to persons linked to the given company entity.")
}).passthrough();
const listPeopleTool = defineApiBackedAiTool({
  name: "customers.list_people",
  displayName: "List people",
  description: "Search / list people (CRM persons) for the caller tenant + organization. Returns { items, total, limit, offset }.",
  inputSchema: listPeopleInput,
  requiredFeatures: ["customers.people.view"],
  toOperation: async (input, ctx) => {
    const { tenantId } = assertTenantScope(ctx);
    const limit = input.limit ?? 50;
    const offset = input.offset ?? 0;
    const page = Math.floor(offset / limit) + 1;
    const query = {
      page,
      pageSize: limit
    };
    if (input.q?.trim()) query.search = input.q.trim();
    if (input.tags && input.tags.length > 0) query.tagIds = input.tags.join(",");
    if (input.companyId) {
      const em = resolveEm(ctx);
      const profiles = await findWithDecryption(
        em,
        CustomerPersonProfile,
        { tenantId, company: input.companyId },
        void 0,
        buildScope(ctx, tenantId)
      );
      const ids = profiles.map((profile) => {
        const entity = profile.entity;
        if (!entity) return null;
        if (typeof entity === "string") return entity;
        const candidate = entity.id;
        return typeof candidate === "string" ? candidate : null;
      }).filter((value) => typeof value === "string" && value.length > 0);
      query.ids = ids.length ? ids.join(",") : NIL_UUID;
    }
    const operation = {
      method: "GET",
      path: "/customers/people",
      query
    };
    return operation;
  },
  mapResponse: (response, input) => {
    const limit = input.limit ?? 50;
    const offset = input.offset ?? 0;
    const data = response.data ?? {};
    const rawItems = Array.isArray(data.items) ? data.items : [];
    return {
      items: rawItems.map((row) => toCustomerListSummary(row)),
      total: typeof data.total === "number" ? data.total : 0,
      limit,
      offset
    };
  }
});
const getPersonInput = z.object({
  personId: z.string().uuid().describe("Person entity id (UUID)."),
  includeRelated: z.boolean().optional().describe("When true, include notes, activities, deals, addresses, tasks, and tags (each capped at 100).")
});
const getPersonTool = {
  name: "customers.get_person",
  displayName: "Get person",
  description: "Fetch a person customer record by id with profile fields and (optionally) notes, activities, deals, addresses, tasks, tags, and custom fields. Returns { found: false } when the record is outside tenant/org scope or missing.",
  inputSchema: getPersonInput,
  requiredFeatures: ["customers.people.view"],
  tags: ["read", "customers"],
  handler: async (rawInput, ctx) => {
    const { tenantId } = assertTenantScope(ctx);
    const input = getPersonInput.parse(rawInput);
    const includeRelated = !!input.includeRelated;
    const operation = {
      method: "GET",
      path: `/customers/people/${input.personId}`
    };
    if (includeRelated) {
      operation.query = { include: "addresses,comments,activities,interactions,deals,todos" };
    }
    const runner = createAiApiOperationRunner(ctx);
    const response = await runner.run(operation);
    if (!response.success) {
      if (response.statusCode === 404 || response.statusCode === 403) {
        return { found: false, personId: input.personId };
      }
      throw new Error(response.error ?? `Failed to fetch person ${input.personId}`);
    }
    const data = response.data ?? {};
    const personRow = data.person ?? null;
    if (!personRow) {
      return { found: false, personId: input.personId };
    }
    const profileRow = data.profile ?? null;
    const customFields = data.customFields ?? {};
    let related = null;
    if (includeRelated) {
      related = buildRelatedRecords(data);
    }
    return {
      found: true,
      person: {
        id: personRow.id,
        displayName: personRow.displayName ?? null,
        description: personRow.description ?? null,
        primaryEmail: personRow.primaryEmail ?? null,
        primaryPhone: personRow.primaryPhone ?? null,
        status: personRow.status ?? null,
        lifecycleStage: personRow.lifecycleStage ?? null,
        source: personRow.source ?? null,
        ownerUserId: personRow.ownerUserId ?? null,
        organizationId: personRow.organizationId ?? null,
        tenantId: personRow.tenantId ?? null,
        createdAt: toIso(personRow.createdAt),
        updatedAt: toIso(personRow.updatedAt)
      },
      profile: profileRow ? {
        id: profileRow.id,
        firstName: profileRow.firstName ?? null,
        lastName: profileRow.lastName ?? null,
        preferredName: profileRow.preferredName ?? null,
        jobTitle: profileRow.jobTitle ?? null,
        department: profileRow.department ?? null,
        seniority: profileRow.seniority ?? null,
        timezone: profileRow.timezone ?? null,
        linkedInUrl: profileRow.linkedInUrl ?? null,
        twitterUrl: profileRow.twitterUrl ?? null,
        companyEntityId: profileRow.companyEntityId ?? null
      } : null,
      customFields,
      related
    };
  }
};
const peopleAiTools = [listPeopleTool, getPersonTool];
var people_pack_default = peopleAiTools;
export {
  people_pack_default as default,
  peopleAiTools
};
//# sourceMappingURL=people-pack.js.map
