/* Copyright (C) 2024-2025 LibreWeddingPlanner contributors*/

'use client';

import { AbstractApi } from '@/app/api/abstract-api';
import { Group, GroupSerializer } from '@/app/lib/group';
import { AdjustmentsHorizontalIcon, PencilIcon, TrashIcon } from '@heroicons/react/24/outline';
import { Column } from 'primereact/column';
import { TreeNode } from 'primereact/treenode';
import { TreeTable } from 'primereact/treetable';

export default function GroupsTable({ groups, onUpdate, onEdit, onEditAffinities }: {
  groups: Group[],
  onUpdate: () => void,
  onEdit: (group: Group) => void,
  onEditAffinities: (group: Group) => void,
}) {

  const api = new AbstractApi<Group>();
  const serializer = new GroupSerializer();

  const actions = (group: Group) => (
    <div className="flex flex-row items-center">
      <TrashIcon className='size-6 cursor-pointer' onClick={() => { api.destroy(serializer, group, onUpdate) }} />
      <PencilIcon className='size-6 cursor-pointer' onClick={() => onEdit(group)} />
      <AdjustmentsHorizontalIcon className='size-6 cursor-pointer' onClick={() => onEditAffinities(group)} />
    </div>
  );

  const index = groups.reduce((acc, group) => {
    if (group.id) {
      acc.set(group.id, group)
    }

    return acc;
  }, new Map());

  groups.forEach(group => group.children = []);
  groups.forEach(group => {
    if (group.parentId) {
      const parent = index.get(group.parentId);
      if (parent) {
        if (!parent.children) {
          parent.children = [];
        }
        parent.children.push(group);
      }
    }
  });

  const renderTree = (group: Group): TreeNode => {
    const childrenAttendance = (group.children || []).reduce((acc, child) => {
      acc.confirmed += child.attendance?.confirmed || 0;
      acc.tentative += child.attendance?.tentative || 0;
      acc.invited += child.attendance?.invited || 0;
      acc.declined += child.attendance?.declined || 0;
      acc.considered += child.attendance?.considered || 0;
      acc.total += child.attendance?.total || 0;
      return acc;
    }, { confirmed: 0, tentative: 0, invited: 0, declined: 0, considered: 0, total: 0 });

    return {
      id: group.id,
      key: group.id,
      label: group.name,
      data: {
        name: group.name,
        color: <div className="w-8 h-8 rounded-full" style={{ backgroundColor: group.color }} />,
        confirmed: childrenAttendance.confirmed + (group.attendance?.confirmed || 0),
        tentative: childrenAttendance.tentative + (group.attendance?.tentative || 0),
        pending: childrenAttendance.invited + (group.attendance?.invited || 0),
        declined: childrenAttendance.declined + (group.attendance?.declined || 0),
        considered: childrenAttendance.considered + (group.attendance?.considered || 0),
        total: childrenAttendance.total + (group.attendance?.total || 0),
        actions: actions(group),
      },
      children: group.children?.map(renderTree),
    }
  }

  const nodes: TreeNode[] = groups
    .filter(group => !group.parentId)
    .map(renderTree)

  const headers = ['Name', 'Color', 'Confirmed', 'Tentative', 'Pending', 'Declined', 'Considered', 'Total', 'Actions'];
  const rowClassName = () => {
    return { 'border-b odd:bg-white even:bg-gray-50 hover:bg-gray-100': true };
  }

  return (
    <>
      <TreeTable value={nodes} rowClassName={rowClassName} className='py-4'>
        <Column expander field="name" header="Name" className='w-2/5' />
        <Column field="color" header="Color" bodyClassName="text-sm" />
        <Column field="confirmed" header="Confirmed" bodyClassName="text-sm" />
        <Column field="tentative" header="Tentative" bodyClassName="text-sm" />
        <Column field="pending" header="Pending" bodyClassName="text-sm" />
        <Column field="declined" header="Declined" bodyClassName="text-sm" />
        <Column field="considered" header="Considered" bodyClassName="text-sm" />
        <Column field="total" header="Total" bodyClassName="text-sm" />
        <Column field="actions" header="Actions" />
      </TreeTable>
    </>
  )
}