import { faker } from "@faker-js/faker";
import type { ComponentStory, ComponentMeta } from "@storybook/react";
import { ColumnDef } from "@tanstack/react-table";
import Pagination from "../pagination/pagination";
import { Table } from "./table";

export type Person = {
    firstName: string;
    lastName: string;
    age: number;
    visits: number;
    progress: number;
    status: "relationship" | "complicated" | "single";
    createdAt: Date;
    subRows?: Person[];
};

const range = (len: number) => {
    const arr = [];
    for (let i = 0; i < len; i++) {
        arr.push(i);
    }
    return arr;
};

const newPerson = (): Person => {
    return {
        firstName: faker.name.firstName(),
        lastName: faker.name.lastName(),
        age: faker.datatype.number(40),
        visits: faker.datatype.number(1000),
        progress: faker.datatype.number(100),
        createdAt: faker.datatype.datetime({ max: new Date().getTime() }),
        status: faker.helpers.shuffle<Person["status"]>([
            "relationship",
            "complicated",
            "single",
        ])[0]!,
    };
};

function makeData(...lens: number[]) {
    const makeDataLevel = (depth = 0): Person[] => {
        const len = lens[depth]!;
        return range(len).map((d): Person => {
            return {
                ...newPerson(),
                subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined,
            };
        });
    };

    return makeDataLevel();
}

const Story: ComponentMeta<typeof Table> = {
    component: Table,
    title: "Table",
};
export default Story;

const Template: ComponentStory<typeof Table> = args => <Table {...args} />;

const columns: ColumnDef<Person>[] = [
    {
        header: "Name",
        footer: props => props.column.id,
        columns: [
            {
                id: "firstName",
                accessorKey: "firstName",
                cell: info => info.getValue(),
                footer: props => props.column.id,
                header: () => <span>First Name</span>,
            },
            {
                accessorFn: row => row.lastName,
                id: "lastName",
                cell: info => info.getValue(),
                header: () => <span>Last Name</span>,
                footer: props => props.column.id,
            },
        ],
    },
    {
        header: "Info",
        footer: props => props.column.id,
        columns: [
            {
                accessorKey: "age",
                header: () => "Age",
                footer: props => props.column.id,
            },
            {
                header: "More Info",
                columns: [
                    {
                        accessorKey: "visits",
                        header: () => <span>Visits</span>,
                        footer: props => props.column.id,
                    },
                    {
                        accessorKey: "status",
                        header: "Status",
                        footer: props => props.column.id,
                    },
                    {
                        accessorKey: "progress",
                        header: "Profile Progress",
                        footer: props => props.column.id,
                    },
                ],
            },
        ],
    },
];

const Primary = Template.bind({});

Primary.args = {
    columns,
    data: makeData(500),
    footer: table => {
        return (
            <Pagination
                count={table.getPageCount()}
                page={table.getState().pagination.pageIndex}
                onChange={page => table.setPageIndex(page)}
            />
        );
    },
    enableRowSelection: true,
};

const people = [
    {
        name: "Lindsay Walton",
        title: "Front-end Developer",
        department: "Optimization",
        email: "lindsay.walton@example.com",
        role: "Member",
        status: "Active",
        image: "https://images.unsplash.com/photo-1517841905240-472988babdf9?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80",
    },
    {
        name: "Lindsay Walton",
        title: "Front-end Developer",
        department: "Optimization",
        email: "lindsay.walton@example.com",
        role: "Member",
        status: "Active",
        image: "https://images.unsplash.com/photo-1517841905240-472988babdf9?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80",
    },
    {
        name: "Lindsay Walton",
        title: "Front-end Developer",
        department: "Optimization",
        email: "lindsay.walton@example.com",
        role: "Member",
        status: "Active",
        image: "https://images.unsplash.com/photo-1517841905240-472988babdf9?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80",
    },
];

const Secondary = Template.bind({});

Secondary.args = {
    columns: [
        {
            header: "Name",
            accessorKey: "name",
            cell: ({ getValue }) => (
                <div className="flex items-center">
                    <div className="h-10 w-10 flex-shrink-0">
                        <img
                            className="h-10 w-10 rounded-full"
                            src={getValue().image}
                            alt=""
                        />
                    </div>
                    <div className="ml-4">
                        <div className="font-medium text-gray-900">
                            {getValue().name}
                        </div>
                        <div className="text-gray-500">{getValue().email}</div>
                    </div>
                </div>
            ),
        },
        {
            header: "Status",
            accessorKey: "status",
        },
        {
            header: "Role",
            accessorKey: "role",
        },
        {
            header: "Email address",
            accessorKey: "email",
        },
    ] as ColumnDef<Person, any>[],
    data: people.map(
        ({ name, department, email, image, role, status, title }) => ({
            name: { name, email, image },
            status,
            role,
            email,
            department,
            title,
        })
    ),
    header: () => (
        <div className="sm:flex sm:items-center px-6 py-3">
            <div className="sm:flex-auto">
                <h1 className="text-xl font-semibold text-gray-900">Users</h1>
                <p className="mt-2 text-sm text-gray-700">
                    A list of all the users in your account including their
                    name, title, email and role.
                </p>
            </div>
            <div className="mt-4 sm:mt-0 sm:ml-16 sm:flex-none">
                <button
                    type="button"
                    className="inline-flex items-center justify-center rounded-md border border-transparent bg-indigo-600 px-4 py-2 text-sm font-medium text-white shadow-sm hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 sm:w-auto"
                >
                    Add user
                </button>
            </div>
        </div>
    ),
};
