import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import Highcharts from 'highcharts'
import HighchartsReact from 'highcharts-react-official'
import { Col, Row } from 'reactstrap'
import { format_angka } from '../util'
import collect from 'collect.js'
import jquery from 'jquery'

import { Sidebar } from 'primereact/sidebar'
import '/node_modules/primeflex/primeflex.css'
import { MantineReactTable, useMantineReactTable } from 'mantine-react-table'
import { Text } from '@mantine/core'

import { QueryClient, QueryClientProvider, useInfiniteQuery } from '@tanstack/react-query'
import dayjs from 'dayjs'
var relativeTime = require('dayjs/plugin/relativeTime')
var customParseFormat = require('dayjs/plugin/customParseFormat')
const fetchSize = 101

const SPTTahunan = ({ dataSend }) => {
  const base_url = '<?=base_url()?>'

  const refChart = useRef(null)
  const [data, setData] = useState(null)

  const [visibleSidebar, setVisibleSidebar] = useState(false)
  const [query, setQuery] = useState(null)

  useEffect(() => {
    jquery.get({
      url: base_url + 'kewilayahan/kytp/sebaranSPTTahunan',
      dataType: 'json',
      type: 'POST',
      data: {
        ...dataSend
      },
      success: (data) => {
        setData(data.data)
      }
    })
  }, [dataSend])

  const optionsChart = (data, title) => {
    const total_wp = collect(data).sum('y')
    return {
      chart: {
        plotBackgroundColor: null,
        plotBorderWidth: null,
        plotShadow: false,
        type: 'pie',
        zoomType: 'xy',
        height: '300'
      },
      title: {
        text: title,
        style: { fontSize: '10px' }
      },
      tooltip: {
        pointFormat: '<b>{point.percentage:.1f}%</b><br>: {point.y} dari ' + format_angka(total_wp) + ' total NPWP yang ada'
      },
      accessibility: {
        point: {
          valueSuffix: '%'
        }
      },
      plotOptions: {
        pie: {
          allowPointSelect: true,
          cursor: 'pointer',
          dataLabels: {
            enabled: true,
            style: { fontSize: '10px' },
            format: '{point.name}: <br> {point.percentage:.1f} %'
          }
        },
        series: {
          cursor: 'pointer',
          point: {
            events: {
              click: function (a) {
                setQuery(this.key)
                setVisibleSidebar(true)
              }
            }
          }
        }
      },
      series: [
        {
          name: '',
          data
        }
      ]
    }
  }

  const TableDetailGraph = ({ dataSend, query, tahunBulan }) => {
    const tableContainerRef = useRef(null)
    const rowVirtualizerInstanceRef = useRef(null)
    const [columnFilters, setColumnFilters] = useState([])
    const [globalFilter, setGlobalFilter] = useState()
    const [sorting, setSorting] = useState([])
    const base_url = '<?=base_url()?>'
    const { data, fetchNextPage, isError, isFetching, isLoading } = useInfiniteQuery({
      queryKey: ['table-data', columnFilters, globalFilter, sorting],

      queryFn: async ({ pageParam = 0 }) => {
        const url = new URL(base_url + 'kewilayahan/sebaran/spttahunan/detail')
        url.searchParams.set('start', `${pageParam * fetchSize}`)
        url.searchParams.set('size', `${fetchSize}`)
        url.searchParams.set('filters', JSON.stringify(columnFilters ?? []))
        url.searchParams.set('globalFilter', globalFilter ?? '')
        url.searchParams.set('sorting', JSON.stringify(sorting ?? []))

        const response = await fetch(url.href, {
          method: 'POST',
          headers: {
            Accept: 'application/json',
            'Content-Type': 'application/json'
          },
          body: JSON.stringify({
            query,
            ...dataSend
          })
        })

        const json = await response.json()
        return json
      },
      getNextPageParam: (_lastGroup, groups) => groups.length,
      keepPreviousData: true,
      refetchOnWindowFocus: false
    })

    const flatData = useMemo(() => data?.pages.flatMap((page) => page.data) ?? [], [data])
    const totalDBRowCount = data?.pages?.[0]?.meta?.totalRowCount ?? 0
    const totalFetched = flatData.length

    const fetchMoreOnBottomReached = useCallback(
      (containerRefElement) => {
        if (containerRefElement) {
          const { scrollHeight, scrollTop, clientHeight } = containerRefElement
          //once the user has scrolled within 400px of the bottom of the table, fetch more data if we can
          if (scrollHeight - scrollTop - clientHeight < 400 && !isFetching && totalFetched < totalDBRowCount) {
            fetchNextPage()
          }
        }
      },

      [fetchNextPage, isFetching, totalFetched, totalDBRowCount]
    )

    const columns = [
      {
        accessorKey: 'NPWP',
        header: 'NPWP',
        enableClickToCopy: true,
        size: 150
      },
      {
        accessorKey: 'NAMA_WP',
        header: 'Nama'
      },
      {
        accessorKey: 'ALAMAT_MFWP',
        header: 'Alamat'
      },
      {
        accessorKey: 'KELURAHAN_MFWP',
        header: 'Wil. Adm.',
        Cell: (data) => {
          const dataRow = data.row.original
          return `${dataRow.KELURAHAN_MFWP ?? ''} ${dataRow.KECAMATAN_MFWP ?? ''} ${dataRow.KOTA_MFWP ?? ''} ${dataRow.PROPINSI_MFWP ?? ''}`
        }
      },
      {
        accessorKey: 'STATUS_WP_MFWP',
        header: 'Status WP'
      },
      {
        accessorKey: 'JNS_WP_MFWP',
        header: 'Jenis WP'
      },
      {
        accessorKey: 'NM_KANTOR',
        header: 'KPP Terdaftar'
      },
      {
        accessorKey: 'NAMA_AR_MFWP',
        header: 'AR'
      },
      {
        accessorKey: 'FLAG_WPS_WPK',
        header: 'WPS/WPK',
        size: 100,
        mantineTableBodyCellProps: {
          align: 'center'
        }
      },
      {
        accessorKey: 'JUMLAH_PEMBAYARAN_THN_TERAKHIR',
        header: 'Rp',
        Cell: ({ cell }) => parseFloat(cell.getValue()).toLocaleString('id-ID'),
        mantineTableHeadCellProps: {
          align: 'right'
        },
        mantineTableBodyCellProps: {
          align: 'right'
        },
        size: 100
      },
      {
        accessorKey: 'KETERANGAN',
        header: 'SPT'
      },
      {
        accessorKey: 'TANGGAL_DAFTAR',
        header: 'Tgl Daftar',
        Cell: ({ cell }) => {
          return dayjs(cell.getValue(), 'DD-MMM-YY').format('YYYY-MM-DD')
        }
      }
    ]

    useEffect(() => {
      if (rowVirtualizerInstanceRef.current) {
        try {
          rowVirtualizerInstanceRef.current.scrollToIndex(0)
        } catch (e) {
          console.error(e)
        }
      }
    }, [sorting, columnFilters, globalFilter])

    //a check on mount to see if the table is already scrolled to the bottom and immediately needs to fetch more data

    useEffect(() => {
      fetchMoreOnBottomReached(tableContainerRef.current)
    }, [fetchMoreOnBottomReached])

    const table1 = useMantineReactTable({
      columns,
      data: flatData,
      enablePagination: false,
      enableRowNumbers: true,
      enableRowVirtualization: true, //optional, but recommended if it is likely going to be more than 100 rows
      manualFiltering: true,
      manualSorting: true,
      mantineTableContainerProps: {
        ref: tableContainerRef, //get access to the table container element
        sx: { maxHeight: '600px' }, //give the table a max height
        onScroll: (
          event //add an event listener to the table container element
        ) => fetchMoreOnBottomReached(event.target)
      },
      mantineToolbarAlertBannerProps: {
        color: 'red',
        children: 'Error loading data'
      },
      onColumnFiltersChange: setColumnFilters,
      onGlobalFilterChange: setGlobalFilter,
      onSortingChange: setSorting,
      renderBottomToolbarCustomActions: () => (
        <Text className="text-sm">
          Fetched {totalFetched} of {totalDBRowCount} total rows.
        </Text>
      ),
      state: {
        columnFilters,
        globalFilter,
        isLoading,
        showAlertBanner: isError,
        showProgressBars: isFetching,
        sorting
      },
      rowVirtualizerInstanceRef, //get access to the virtualizer instance
      rowVirtualizerProps: { overscan: 10 },
      mantineTableBodyCellProps: { className: 'p-1 text-xs' },
      mantineTableBodyProps: { className: 'mb-3' }
    })

    return <MantineReactTable table={table1} />
  }

  const queryClient = new QueryClient()

  return (
    <>
      <Row>
        <Col>
          <HighchartsReact ref={refChart} highcharts={Highcharts} options={optionsChart(data, 'SPT Tahunan')} />
        </Col>
      </Row>
      <Row>
        <Col>
          <Sidebar
            header={
              <>
                <h4>Detail Data</h4>
              </>
            }
            visible={visibleSidebar}
            position="bottom"
            onHide={() => setVisibleSidebar(false)}
            style={{ height: 'calc(100vh - 100px)' }}
            blockScroll
            pt={{ header: { className: 'p-1' }, closeButton: { style: { width: '2rem', height: '1rem' } } }}
          >
            <Row>
              <Col>
                <QueryClientProvider client={queryClient}>
                  <TableDetailGraph dataSend={dataSend} query={query} />
                </QueryClientProvider>
              </Col>
            </Row>
          </Sidebar>
        </Col>
      </Row>
    </>
  )
}

export default SPTTahunan