import React from "react";
import f3, { f3Data } from "family-chart";
import "./family-chart.css";
import { FamilyTreeNode } from "../../utils/family_tree";
import { fmtDate } from "../../api/MemberApi";

export function ComplexFamilyTree(p: {
  tree: FamilyTreeNode;
}): React.ReactElement {
  const refCb = (container: HTMLDivElement) => {
    if (!container) return;

    const store = f3.createStore({
        data: treeToF3Data(p.tree),
        node_separation: 250,
        level_separation: 150,
      }),
      view = f3.d3AnimationView({
        store,
        cont: document.querySelector("#FamilyChart"),
      }),
      Card = f3.elements.Card({
        store,
        svg: view.svg,
        card_dim: {
          w: 220,
          h: 70,
          text_x: 75,
          text_y: 15,
          img_w: 60,
          img_h: 60,
          img_x: 5,
          img_y: 5,
        },
        card_display: [
          (d) => `${d.data.first_name || ""} ${d.data.last_name || ""}`,
          (d) => `${d.data["birthday"] || ""}`,
        ],
        mini_tree: true,
        link_break: false,
      });

    view.setCard(Card);
    store.setOnUpdate((props) => view.update(props || {}));
    store.update.tree({ initial: true });
  };

  return <div className="f3" id="FamilyChart" ref={refCb}></div>;
}

function treeToF3Data(node: FamilyTreeNode): f3Data[] {
  const availableMembers = new Set<number>();
  getAvailableMembers(node, availableMembers);

  const list: f3Data[] = [];
  treeToF3DataRecurse(node, list, availableMembers);
  console.info(list);
  return list;
}

function getAvailableMembers(t: FamilyTreeNode, s: Set<number>) {
  s.add(t.member.id);

  t.couples?.forEach((c) => {
    s.add(c.member.id);
    c.down.forEach((e) => getAvailableMembers(e, s));
  });

  t.down?.forEach((e) => getAvailableMembers(e, s));
}

function treeToF3DataRecurse(
  node: FamilyTreeNode,
  array: f3Data[],
  availableMembers: Set<number>
) {
  // Get all members ids
  const children = node?.down?.map((c) => c.member.id.toString()) ?? [];
  node.couples?.map((c) =>
    c.down.forEach((m) => children.push(m.member.id.toString()))
  );

  array.push({
    data: {
      first_name: node.member.first_name ?? "_",
      last_name: node.member.last_name ?? "_",
      gender: node.member.sex ?? "M",
      avatar: node.member.thumbnailURL ?? undefined,
      birthday: node.member.dateOfBirth
        ? fmtDate(node.member.dateOfBirth)
        : undefined,
    },
    id: node.member.id.toString(),
    rels: {
      father:
        node.member.father && availableMembers.has(node.member.father)
          ? node.member.father.toString()
          : undefined,
      mother:
        node.member.mother && availableMembers.has(node.member.mother)
          ? node.member.mother.toString()
          : undefined,

      spouses: node.couples?.map((c) => c.member.id.toString()),
      children: children,
    },
  });

  node?.down?.forEach((e) => treeToF3DataRecurse(e, array, availableMembers));

  if (node.couples) {
    for (const c of node.couples) {
      array.push({
        data: {
          first_name: c.member.first_name ?? "_",
          last_name: c.member.last_name ?? "_",
          gender: c.member.sex ?? "M",
          avatar: c.member.thumbnailURL ?? undefined,
          birthday: c.member.dateOfBirth
            ? fmtDate(c.member.dateOfBirth)
            : undefined,
        },
        id: c.member.id.toString(),
        rels: {
          father:
            c.member.father && availableMembers.has(c.member.father)
              ? c.member.father.toString()
              : undefined,
          mother:
            c.member.mother && availableMembers.has(c.member.mother)
              ? c.member.mother.toString()
              : undefined,
          spouses: [node.member.id.toString()],
          children: c.down.map((c) => c.member.id.toString()),
        },
      });

      c.down.forEach((e) => treeToF3DataRecurse(e, array, availableMembers));
    }
  }
}

/*
import { jsPDF } from "jspdf";
import "svg2pdf.js";

setTimeout(() => {
      const doc = new jsPDF({
        orientation: "l",
        format: [1000, 1000],
      });

      const element = document.getElementById("FamilyChart");
      console.log(element);
      doc.svg(element!.children[0], { height: 1000, width: 1000 }).then(() => {
        // save the created pdf
        //doc.save("myPDF.pdf");
      });
    }, 6000);*/
