"use client"

// Checkbox tree for assigning a role's visible sidebar sections. Leaf nav items
// (no children) are toggled directly; parent nav items with children are a
// "select all children" convenience toggle — the parent's own visibility is
// derived from its children on the frontend (see AppSidebar.tsx's filter), so
// only the children need to carry the actual grant for those groups.
import { Checkbox } from "@/components/ui/checkbox"
import { Label } from "@/components/ui/label"
import { NavItem } from "@/types/rbac"

interface Props {
  tree: NavItem[]
  selectedNavItemIds: Set<number>
  selectedSubNavItemIds: Set<number>
  onChange: (navItemIds: Set<number>, subNavItemIds: Set<number>) => void
}

export function RolePermissionTree({ tree, selectedNavItemIds, selectedSubNavItemIds, onChange }: Props) {
  function toggleLeaf(navItemId: number) {
    const next = new Set(selectedNavItemIds)
    if (next.has(navItemId)) next.delete(navItemId)
    else next.add(navItemId)
    onChange(next, selectedSubNavItemIds)
  }

  function toggleChild(subNavItemId: number) {
    const next = new Set(selectedSubNavItemIds)
    if (next.has(subNavItemId)) next.delete(subNavItemId)
    else next.add(subNavItemId)
    onChange(selectedNavItemIds, next)
  }

  function toggleAllChildren(item: NavItem, checked: boolean) {
    const next = new Set(selectedSubNavItemIds)
    for (const child of item.children) {
      if (checked) next.add(child.subNavItemId)
      else next.delete(child.subNavItemId)
    }
    onChange(selectedNavItemIds, next)
  }

  return (
    <div className="flex flex-col gap-1 rounded-lg border p-4">
      {tree.map((item) => {
        if (item.children.length === 0) {
          return (
            <label key={item.navItemId} className="flex items-center gap-3 rounded-md px-2 py-2 hover:bg-muted/50">
              <Checkbox
                checked={selectedNavItemIds.has(item.navItemId)}
                onCheckedChange={() => toggleLeaf(item.navItemId)}
              />
              <Label className="cursor-pointer text-base font-medium">{item.label}</Label>
            </label>
          )
        }

        const checkedCount = item.children.filter((c) => selectedSubNavItemIds.has(c.subNavItemId)).length
        const allChecked = checkedCount === item.children.length

        return (
          <div key={item.navItemId} className="flex flex-col gap-1 border-t pt-2 first:border-t-0 first:pt-0">
            <label className="flex items-center gap-3 rounded-md px-2 py-2 hover:bg-muted/50">
              <Checkbox checked={allChecked} onCheckedChange={(checked) => toggleAllChildren(item, !!checked)} />
              <Label className="cursor-pointer text-base font-semibold">
                {item.label} {checkedCount > 0 && !allChecked && <span className="text-sm font-normal text-muted-foreground">({checkedCount} of {item.children.length})</span>}
              </Label>
            </label>
            <div className="flex flex-col gap-1 pl-9">
              {item.children.map((child) => (
                <label key={child.subNavItemId} className="flex items-center gap-3 rounded-md px-2 py-1.5 hover:bg-muted/50">
                  <Checkbox
                    checked={selectedSubNavItemIds.has(child.subNavItemId)}
                    onCheckedChange={() => toggleChild(child.subNavItemId)}
                  />
                  <Label className="cursor-pointer text-sm">{child.label}</Label>
                </label>
              ))}
            </div>
          </div>
        )
      })}
    </div>
  )
}
