#!/usr/bin/env bun
/**
 * Twenty CRM — create saved views for the lead funnel.
 * Run inside the rspace container:
 *   docker exec -e TWENTY_API_TOKEN=... -e TWENTY_API_URL=... rspace-online bun /app/scripts/twenty-views.js
 *
 * Field IDs are discovered dynamically via metadata introspection,
 * so this script works on any Twenty instance.
 */

const TOKEN = process.env.TWENTY_API_TOKEN;
const BASE = process.env.TWENTY_API_URL || "http://twenty-ch-server:3000";

if (!TOKEN) {
  const fs = require("fs");
  try {
    const env = fs.readFileSync("/proc/1/environ", "utf8");
    const match = env.split("\0").find(e => e.startsWith("TWENTY_API_TOKEN="));
    if (match) var FALLBACK = match.split("=").slice(1).join("=");
  } catch {}
  if (!FALLBACK) { console.error("TWENTY_API_TOKEN not set"); process.exit(1); }
  var API_TOKEN = FALLBACK;
} else {
  var API_TOKEN = TOKEN;
}

const HEADERS = {
  Authorization: "Bearer " + API_TOKEN,
  "Content-Type": "application/json",
};

async function gql(query, variables) {
  const r = await fetch(BASE + "/metadata", {
    method: "POST",
    headers: HEADERS,
    body: JSON.stringify({ query, variables }),
  });
  const d = await r.json();
  if (d.errors) console.error("GQL error:", JSON.stringify(d.errors, null, 2));
  return d.data;
}

// ── Discover object and field IDs dynamically ──
async function discoverIds() {
  // Step 1: Find the opportunity object ID
  const objData = await gql(`{
    objects(paging: { first: 100 }) {
      edges { node { id nameSingular } }
    }
  }`);

  const oppObj = objData.objects.edges.find(e => e.node.nameSingular === "opportunity");
  if (!oppObj) throw new Error("Opportunity object not found");

  const opp = oppObj.node;

  // Step 2: Query fields separately with proper paging
  const fieldData = await gql(`
    query GetFields($id: UUID!) {
      object(id: $id) {
        fields(paging: { first: 200 }) { edges { node { id name } } }
      }
    }
  `, { id: opp.id });

  const fields = fieldData.object.fields.edges.map(e => e.node);
  const fieldMap = {};
  for (const f of fields) fieldMap[f.name] = f.id;

  console.log("Discovered opportunity object:", opp.id);
  console.log("Fields:", Object.keys(fieldMap).join(", "));

  const required = ["stage", "name", "closeDate", "amount"];
  for (const name of required) {
    if (!fieldMap[name]) throw new Error(`Required field '${name}' not found on opportunity object`);
  }

  return {
    oppObjectId: opp.id,
    stageFieldId: fieldMap.stage,
    nameFieldId: fieldMap.name,
    closeDateFieldId: fieldMap.closeDate,
    amountFieldId: fieldMap.amount,
    nextActionDateFieldId: fieldMap.nextActionDate || null,
  };
}

(async () => {
  console.log("=== Creating Twenty CRM Saved Views ===\n");

  const ids = await discoverIds();

  // ── View 1: "My Pipeline" — Kanban grouped by stage ──
  console.log("\nCreating 'My Pipeline' kanban view...");
  const v1 = await gql(`
    mutation CreateView($input: CreateViewInput!) {
      createCoreView(input: $input) { id name type }
    }
  `, {
    input: {
      name: "My Pipeline",
      objectMetadataId: ids.oppObjectId,
      type: "KANBAN",
      icon: "IconLayoutKanban",
      position: 0,
      key: "INDEX",
      visibility: "WORKSPACE",
      mainGroupByFieldMetadataId: ids.stageFieldId,
    },
  });

  if (v1 && v1.createCoreView) {
    const viewId = v1.createCoreView.id;
    console.log("  Created view:", viewId);

    const viewFields = [
      { fieldMetadataId: ids.nameFieldId, position: 0, isVisible: true },
      { fieldMetadataId: ids.stageFieldId, position: 1, isVisible: true },
      { fieldMetadataId: ids.amountFieldId, position: 2, isVisible: true },
      { fieldMetadataId: ids.closeDateFieldId, position: 3, isVisible: true },
    ];
    if (ids.nextActionDateFieldId) {
      viewFields.push({ fieldMetadataId: ids.nextActionDateFieldId, position: 4, isVisible: true });
    }
    for (const vf of viewFields) {
      await gql(`
        mutation CreateViewField($input: CreateViewFieldInput!) {
          createCoreViewField(input: $input) { id }
        }
      `, { input: { viewId, ...vf } });
    }
    console.log("  View fields added");
  } else {
    console.log("  FAILED to create My Pipeline view");
  }

  // ── View 2: "Needs Follow-up" — Table filtered: nextActionDate <= today ──
  if (ids.nextActionDateFieldId) {
    console.log("\nCreating 'Needs Follow-up' table view...");
    const v2 = await gql(`
      mutation CreateView($input: CreateViewInput!) {
        createCoreView(input: $input) { id name type }
      }
    `, {
      input: {
        name: "Needs Follow-up",
        objectMetadataId: ids.oppObjectId,
        type: "TABLE",
        icon: "IconAlarm",
        position: 1,
        key: "INDEX",
        visibility: "WORKSPACE",
      },
    });

    if (v2 && v2.createCoreView) {
      const viewId = v2.createCoreView.id;
      console.log("  Created view:", viewId);

      console.log("  Adding filter: nextActionDate <= today...");
      const fg = await gql(`
        mutation CreateFilterGroup($input: CreateViewFilterGroupInput!) {
          createCoreViewFilterGroup(input: $input) { id }
        }
      `, {
        input: {
          viewId: viewId,
          logicalOperator: "AND",
          positionInViewFilterGroup: 0,
        },
      });

      if (fg && fg.createCoreViewFilterGroup) {
        await gql(`
          mutation CreateFilter($input: CreateViewFilterInput!) {
            createCoreViewFilter(input: $input) { id }
          }
        `, {
          input: {
            viewId: viewId,
            viewFilterGroupId: fg.createCoreViewFilterGroup.id,
            fieldMetadataId: ids.nextActionDateFieldId,
            operand: "IS_BEFORE",
            value: "TODAY",
            positionInViewFilterGroup: 0,
          },
        });
        console.log("  Filter added");
      }

      console.log("  Adding sort: nextActionDate ASC...");
      await gql(`
        mutation CreateSort($input: CreateViewSortInput!) {
          createCoreViewSort(input: $input) { id }
        }
      `, {
        input: {
          viewId: viewId,
          fieldMetadataId: ids.nextActionDateFieldId,
          direction: "ASC",
        },
      });
      console.log("  Sort added");
    } else {
      console.log("  FAILED to create Needs Follow-up view");
    }

    // ── View 3: "Stale Leads" — Table filtered: nextActionDate is empty ──
    console.log("\nCreating 'Stale Leads' table view...");
    const v3 = await gql(`
      mutation CreateView($input: CreateViewInput!) {
        createCoreView(input: $input) { id name type }
      }
    `, {
      input: {
        name: "Stale Leads",
        objectMetadataId: ids.oppObjectId,
        type: "TABLE",
        icon: "IconAlertTriangle",
        position: 2,
        key: "INDEX",
        visibility: "WORKSPACE",
      },
    });

    if (v3 && v3.createCoreView) {
      const viewId = v3.createCoreView.id;
      console.log("  Created view:", viewId);

      console.log("  Adding filter: nextActionDate is empty...");
      const fg = await gql(`
        mutation CreateFilterGroup($input: CreateViewFilterGroupInput!) {
          createCoreViewFilterGroup(input: $input) { id }
        }
      `, {
        input: {
          viewId: viewId,
          logicalOperator: "AND",
          positionInViewFilterGroup: 0,
        },
      });

      if (fg && fg.createCoreViewFilterGroup) {
        await gql(`
          mutation CreateFilter($input: CreateViewFilterInput!) {
            createCoreViewFilter(input: $input) { id }
          }
        `, {
          input: {
            viewId: viewId,
            viewFilterGroupId: fg.createCoreViewFilterGroup.id,
            fieldMetadataId: ids.nextActionDateFieldId,
            operand: "IS_EMPTY",
            value: "",
            positionInViewFilterGroup: 0,
          },
        });
        console.log("  Filter added");
      }
    } else {
      console.log("  FAILED to create Stale Leads view");
    }
  } else {
    console.log("\nSKIPPING follow-up/stale views — nextActionDate field not found.");
    console.log("Run twenty-setup.js first to create custom fields, then re-run this script.");
  }

  console.log("\n=== Views setup complete ===");
})();
