import { Button, Link, Table, Badge } from "@tailor-platform/app-shell";
import { EmptyState } from "@/components/composed/empty-state";
import { graphql, type FragmentOf, readFragment } from "@/graphql";

const UserRowFragment = graphql(`
  fragment UserRow on User {
    id
    name
    email
    status
    userRoles {
      edges {
        node {
          id
          role {
            id
            name
          }
        }
      }
    }
  }
`);

export const UsersTableFragment = graphql(
  `
    fragment UsersTable on UserConnection {
      edges {
        node {
          ...UserRow
        }
      }
    }
  `,
  [UserRowFragment],
);

interface UserRowProps {
  user: FragmentOf<typeof UserRowFragment>;
}

const UserRow = ({ user: userFragment }: UserRowProps) => {
  const user = readFragment(UserRowFragment, userFragment);
  const roles = user.userRoles.edges
    .map((edge) => edge.node.role)
    .filter((r): r is NonNullable<typeof r> => r != null);

  return (
    <Table.Row>
      <Table.Cell>{user.name}</Table.Cell>
      <Table.Cell>{user.email}</Table.Cell>
      <Table.Cell>
        <Badge
          variant={
            user.status === "ACTIVE" ? "success" : user.status === "PENDING" ? "info" : "neutral"
          }
        >
          {user.status}
        </Badge>
      </Table.Cell>
      <Table.Cell>
        {roles.length > 0 ? (
          <div className="flex flex-wrap gap-1">
            {roles.map((role) => (
              <Badge key={role.id} variant="outline-neutral">
                {role.name}
              </Badge>
            ))}
          </div>
        ) : (
          <span className="text-muted-foreground">-</span>
        )}
      </Table.Cell>
      <Table.Cell>
        <Button variant="ghost" size="sm" render={<Link to={user.id} />}>
          View
        </Button>
      </Table.Cell>
    </Table.Row>
  );
};

interface UsersTableProps {
  data: FragmentOf<typeof UsersTableFragment>;
}

export const UsersTable = ({ data }: UsersTableProps) => {
  const connection = readFragment(UsersTableFragment, data);

  return (
    <Table.Root>
      <Table.Header>
        <Table.Row>
          <Table.Head>Name</Table.Head>
          <Table.Head>Email</Table.Head>
          <Table.Head>Status</Table.Head>
          <Table.Head>Roles</Table.Head>
          <Table.Head />
        </Table.Row>
      </Table.Header>
      <Table.Body>
        {connection.edges.length === 0 ? (
          <Table.Row>
            <Table.Cell colSpan={5}>
              <EmptyState
                title="No users"
                message="Get started by creating a new user."
                action={<Button render={<Link to="create" />}>Create User</Button>}
              />
            </Table.Cell>
          </Table.Row>
        ) : (
          connection.edges.map((edge) => {
            const { id } = readFragment(UserRowFragment, edge.node);
            return <UserRow key={id} user={edge.node} />;
          })
        )}
      </Table.Body>
    </Table.Root>
  );
};
