import { Meta } from "@storybook/react";
import { PDFExportProps } from "../PDFExport/PDFExportProps";
import TreeListPDFExport from "./TreeListPDFExport";
import {
  TreeList,
  orderBy,
  filterBy,
  mapTree,
  extendDataItem,
  TreeListTextFilter,
  TreeListNumericFilter,
  TreeListDateFilter,
  TreeListBooleanFilter,
  TreeListToolbar,
  TreeListExpandChangeEvent,
  TreeListDataStateChangeEvent,
  TreeListColumnProps,
} from "@progress/kendo-react-treelist";
import employees from "../TreeListPDFExport/mockData/data";
import { DataState, Employee } from "../TreeListPDFExport/mockData/interfaces";
import React from "react";
import Button from "../../Buttons/Button/Button";

export default {
  title: "Design System/Pdf Processing/TreeListPDFExport",
  component: TreeListPDFExport,
  tags: ["autodocs"],
  parameters: {
    docs: {
      description: {
        component:
          'The KendoReact TreeList provides options for exporting to PDF. To enable the PDF export, you need to wrap the TreeList inside a TreeListPDFExport component. \n\n```javascript\nimport { TreeListPDFExport } from "@renault-ui-library"\n```',
      },
    },
  },
  argTypes: {
    dataTestId: {
      control: { type: "text" },
      description: "Specifies the data-test-id attribute for testing purposes.",
    },
    allPages: {
      control: { type: "boolean" },
      description:
        "If set to true it will export all pages of the TreeList data. By default allPages is set to false.",
    },
    author: {
      control: { type: "text" },
      description: "The author (metadata) of the PDF document.",
    },
    avoidLinks: {
      control: { type: "text" },
      description:
        "A flag that indicates whether to produce actual hyperlinks in the exported PDF file.",
    },
    creator: {
      control: { type: "text" },
      description:
        "The creator of the PDF document. Defaults to KendoReact PDF Generator.",
    },
    date: {
      control: { type: "date" },
      description:
        "The date when the PDF document is created. Defaults to new Date().",
    },
    fileName: {
      control: { type: "text" },
      description:
        "Specifies the name of the exported PDF file. Defaults to export.pdf.",
    },
    forcePageBreak: {
      control: { type: "text" },
      description:
        "An optional CSS selector that specifies the elements which cause the page breaks.",
    },
    forceProxy: {
      control: { type: "boolean" },
      description:
        "If set to true, the content is forwarded to proxyURL even if the browser supports local saving of files.",
    },
    imageResolution: {
      control: { type: "number" },
      description:
        "The forced resolution of the images in the exported PDF document. By default, the images are exported at their full resolution.",
    },
    keepTogether: {
      control: { type: "text" },
      description:
        "An optional CSS selector that specifies the elements which should not be split across the pages.",
    },
    keywords: {
      control: { type: "text" },
      description: "The keywords (metadata) of the PDF document.",
    },
    landscape: {
      control: { type: "boolean" },
      description:
        "A flag that indicates if the page will be in a landscape orientation. By default, the page is in a portrait orientation. Defaults to false.",
    },
    margin: {
      control: { type: "text" },
      description: "Specifies the margins of the page.",
    },
    pageTemplate: {
      control: { type: "text" },
      description:
        "A React functional or class component which is used as a template that is inserted into each page of the PDF document.",
    },
    paperSize: {
      control: { type: "text" },
      description:
        'Specifies the paper size of the PDF document. Defaults to "auto".',
    },
    producer: {
      control: { type: "text" },
      description: "The producer (metadata) of the PDF document.",
    },
    proxyData: {
      control: { type: "object" },
      description:
        "A key/value dictionary of form values which will be sent to the proxy.",
    },
    proxyTarget: {
      control: { type: "text" },
      description:
        "A name or keyword which indicates where to display the document that is returned from the proxy.",
    },
    proxyURL: {
      control: { type: "text" },
      description:
        "The URL of the server-side proxy which streams the file to the end user.",
    },
    repeatHeaders: {
      control: { type: "boolean" },
      description:
        "Specifies if the <thead> elements of the tables will be repeated on each page.",
    },
    scale: {
      control: { type: "number" },
      description: "A scale factor. Defaults to 1.",
    },
    subject: {
      control: { type: "text" },
      description: "The subject (metadata) of the PDF document.",
    },
    title: {
      control: { type: "text" },
      description: "The title (metadata) of the PDF document.",
    },
  },
} as Meta;

export const Default = (args: PDFExportProps): JSX.Element => {
  const subItemsField: string = "employees";
  const expandField: string = "expanded";
  const columns: TreeListColumnProps[] = [
    {
      field: "name",
      title: "Name",
      width: "250px",
      filter: TreeListTextFilter,
      expandable: true,
    },
    {
      field: "hireDate",
      title: "Hire Date",
      width: "200px",
      format: "{0:d}",
      filter: TreeListDateFilter,
    },
    {
      field: "timeInPosition",
      title: "Year(s) in Position",
      width: "200px",
      filter: TreeListNumericFilter,
    },
    {
      field: "fullTime",
      title: "Full Time",
      width: "100px",
      filter: TreeListBooleanFilter,
    },
  ];

  interface AppState {
    data: Employee[];
    dataState: DataState;
    expanded: number[];
  }

  const gridPDFExport = React.useRef<any>();

  const [state, setState] = React.useState<AppState>({
    data: [...employees],
    dataState: {
      sort: [{ field: "name", dir: "asc" }],
      filter: [],
    },
    expanded: [1, 2, 32],
  });

  const onExpandChange = (e: TreeListExpandChangeEvent) => {
    setState({
      ...state,
      expanded: e.value
        ? state.expanded.filter((id) => id !== e.dataItem.id)
        : [...state.expanded, e.dataItem.id],
    });
  };

  const handleDataStateChange = (event: TreeListDataStateChangeEvent) => {
    setState({
      ...state,
      dataState: {
        ...event.dataState,
        sort: event.dataState.sort || [],
        filter: event.dataState.filter || [],
      },
    });
  };

  const addExpandField = (dataTree: Employee[]) => {
    const expanded = state.expanded;
    return mapTree(dataTree, subItemsField, (item) =>
      extendDataItem(item, subItemsField, {
        [expandField]: expanded.includes(item.id),
      })
    );
  };

  const processData = () => {
    let { data, dataState } = state;
    let filteredData = filterBy(data, dataState.filter, subItemsField);
    let sortedData = orderBy(filteredData, dataState.sort, subItemsField);
    return addExpandField(sortedData);
  };

  const exportPDF = () => {
    if (gridPDFExport !== null) {
      gridPDFExport.current.save();
    }
  };

  const treelist: React.ReactElement = (
    <TreeList
      style={{ maxHeight: "510px", overflow: "auto" }}
      expandField={expandField}
      subItemsField={subItemsField}
      onExpandChange={onExpandChange}
      sortable={{ mode: "multiple" }}
      {...state.dataState}
      data={processData()}
      onDataStateChange={handleDataStateChange}
      columns={columns}
      toolbar={
        <TreeListToolbar>
          <Button onClick={exportPDF}>Export PDF</Button>
        </TreeListToolbar>
      }
    />
  );

  return (
    <>
      {treelist}
      <TreeListPDFExport ref={gridPDFExport}>{treelist}</TreeListPDFExport>
    </>
  );
};

Default.args = {
  dataTestId: "treelist-data-testid",
  allPages: false,
  author: "Author",
  avoidLinks: "true",
  creator: "KendoReact PDF Generator",
  date: new Date(),
  fileName: "export.pdf",
  forcePageBreak: "",
  forceProxy: false,
  imageResolution: 300,
  keepTogether: "",
  keywords: "",
  landscape: false,
  margin: "10mm",
  pageTemplate: "",
  paperSize: "A4",
  producer: "",
  proxyData: {},
  proxyTarget: "",
  proxyURL: "",
  repeatHeaders: false,
  scale: 1,
  subject: "",
  title: "",
};
