import React, { useEffect, useState, useMemo } from 'react'
import { createPortal } from 'react-dom';
import { ToastContainer, toast } from 'react-toastify';
import BaseButton from '../BaseButton'
import CardBoxModal from '../CardBoxModal'
import CardBox from "../CardBox";
import { fetch, update, deleteItem, setRefetch, deleteItemsByIds } from '../../stores/booking_requests/booking_requestsSlice'
import { useAppDispatch, useAppSelector } from '../../stores/hooks'
import { useRouter } from 'next/router'
import { Field, Form, Formik } from "formik";
import {
    DataGrid,
    GridColDef,
} from '@mui/x-data-grid';
import {loadColumns} from "./configureBooking_requestsCols";
import _ from 'lodash';
import dataFormatter from '../../helpers/dataFormatter'
import {dataGridStyles} from "../../styles";


import KanbanBoard from '../KanbanBoard/KanbanBoard';
import axios from 'axios';


const perPage = 10

const compactColumnVisibilityModel = {
  tenant: false,
  organization: false,
  preferred_unit_type: false,
  preferred_bedrooms: false,
  purpose_of_stay: false,
  special_requirements: false,
  budget_code: false,
  currency: false,
  travelers: false,
  approval_steps: false,
  documents: false,
  comments: false,
}


const TableSampleBooking_requests = ({ filterItems, setFilterItems, filters, showGrid }) => {
  const notify = (type, msg) => toast( msg, {type, position: "bottom-center"});

    const dispatch = useAppDispatch();
    const router = useRouter();

    const pagesList = [];
    const [id, setId] = useState(null);
    const [currentPage, setCurrentPage] = useState(0);
    const [filterRequest, setFilterRequest] = React.useState('');
    const [columns, setColumns] = useState<GridColDef[]>([]);
    const [selectedRows, setSelectedRows] = useState([]);
    const [sortModel, setSortModel] = useState([
        {
            field: '',
            sort: 'desc',
        },
    ]);
  
    const [kanbanColumns, setKanbanColumns] = useState<Array<{id: string, label: string}> | null>(null);
    const [kanbanFilters, setKanbanFilters] = useState('');
  
  const { booking_requests, loading, count, notify: booking_requestsNotify, refetch } = useAppSelector((state) => state.booking_requests)
  const { currentUser } = useAppSelector((state) => state.auth);
  const focusRing = useAppSelector((state) => state.style.focusRingColor);
  const bgColor = useAppSelector((state) => state.style.bgLayoutColor);
  const corners = useAppSelector((state) => state.style.corners);
    const numPages = Math.floor(count / perPage) === 0 ? 1 : Math.ceil(count / perPage);
    for (let i = 0; i < numPages; i++) {
        pagesList.push(i);
    }

    const loadData = async (page = currentPage, request = filterRequest) => {
        if (page !== currentPage) setCurrentPage(page);
        if (request !== filterRequest) setFilterRequest(request);
        const { sort, field } = sortModel[0];

      const query = `?page=${page}&limit=${perPage}${request}&sort=${sort}&field=${field}`;
      dispatch(fetch({ limit: perPage, page, query }));
  };

  useEffect(() => {
      if (booking_requestsNotify.showNotification) {
          notify(booking_requestsNotify.typeNotification, booking_requestsNotify.textNotification);
      }
  }, [booking_requestsNotify.showNotification]);

  useEffect(() => {
      if (!currentUser) return;
      loadData();
  }, [sortModel, currentUser]);

  useEffect(() => {
    if (refetch) {
      loadData(0);
      dispatch(setRefetch(false));
    }
  }, [refetch, dispatch]);

  const [isModalInfoActive, setIsModalInfoActive] = useState(false)
  const [isModalTrashActive, setIsModalTrashActive] = useState(false)

  const handleModalAction = () => {
    setIsModalInfoActive(false)
    setIsModalTrashActive(false)
  }

  
    useEffect(() => {
      
        
      
      setKanbanColumns([
          { id: "draft", label: _.startCase("draft") },
          { id: "submitted", label: _.startCase("submitted") },
          { id: "in_review", label: _.startCase("in_review") },
          { id: "changes_requested", label: _.startCase("changes_requested") },
          { id: "approved", label: _.startCase("approved") },
          { id: "rejected", label: _.startCase("rejected") },
          { id: "expired", label: _.startCase("expired") },
          { id: "converted_to_reservation", label: _.startCase("converted_to_reservation") },
          { id: "canceled", label: _.startCase("canceled") },
      ]);
      
      
    }, []);
  

  

  const handleDeleteModalAction = (id: string) => {
    setId(id)
    setIsModalTrashActive(true)
  }
  const handleDeleteAction = async () => {
      if (id) {
          await dispatch(deleteItem(id));
          await loadData(0);
          setIsModalTrashActive(false);
      }
  };

  const bookingKanbanOverview = useMemo(() => {
    const totals = booking_requests.reduce(
      (accumulator, item) => {
        const guestCount = Number(item?.guest_count || 0);
        const status = item?.status || 'draft';

        accumulator.total += 1;
        accumulator.guests += Number.isNaN(guestCount) ? 0 : guestCount;
        accumulator[status] = (accumulator[status] || 0) + 1;

        return accumulator;
      },
      {
        total: 0,
        guests: 0,
        submitted: 0,
        in_review: 0,
        changes_requested: 0,
        approved: 0,
        converted_to_reservation: 0,
      },
    );

    return [
      {
        label: 'Visible requests',
        value: totals.total,
        hint: 'Currently in view',
      },
      {
        label: 'Needs review',
        value: totals.submitted + totals.in_review + totals.changes_requested,
        hint: 'Submitted or in progress',
      },
      {
        label: 'Approved',
        value: totals.approved,
        hint: 'Ready to place',
      },
      {
        label: 'Guests',
        value: totals.guests,
        hint: 'Across visible requests',
      },
    ];
  }, [booking_requests]);

  const generateFilterRequests = useMemo(() => {
    let request = '&';
    filterItems.forEach((item) => {
      const isRangeFilter = filters.find(
        (filter) =>
          filter.title === item.fields.selectedField &&
          (filter.number || filter.date),
      );

      if (isRangeFilter) {
        const from = item.fields.filterValueFrom;
        const to = item.fields.filterValueTo;
        if (from) {
          request += `${item.fields.selectedField}Range=${from}&`;
        }
        if (to) {
          request += `${item.fields.selectedField}Range=${to}&`;
        }
      } else {
        const value = item.fields.filterValue;
        if (value) {
          request += `${item.fields.selectedField}=${value}&`;
        }
      }
    });
    return request;
  }, [filterItems, filters]);

  const deleteFilter = (value) => {
    const newItems = filterItems.filter((item) => item.id !== value);

    if (newItems.length) {
        setFilterItems(newItems);
    } else {
        loadData(0, '');
        
        setKanbanFilters('');
        
        setFilterItems(newItems);
    }
  };

  const handleSubmit = () => {
    loadData(0, generateFilterRequests);
    
    setKanbanFilters(generateFilterRequests);
    
  };

  const handleChange = (id) => (e) => {
    const value = e.target.value;
    const name = e.target.name;

    setFilterItems(
      filterItems.map((item) => {
        if (item.id !== id) return item;
        if (name === 'selectedField') return { id, fields: { [name]: value } };

        return { id, fields: { ...item.fields, [name]: value } }
      }),
    );
  };

  const handleReset = () => {
      setFilterItems([]);
      loadData(0, '');
      
      setKanbanFilters('');
      
  };

  const onPageChange = (page: number) => {
    loadData(page);
    setCurrentPage(page);
  };

  
    useEffect(() => {
        if (!currentUser) return;

        loadColumns(
            handleDeleteModalAction,
            `booking_requests`,
            currentUser,
        ).then((newCols) => setColumns(newCols));
    }, [currentUser]);
  


  const handleTableSubmit = async (id: string, data) => {
    
    if (!_.isEmpty(data)) {
      await dispatch(update({ id, data }))
        .unwrap()
        .then((res) => res)
        .catch((err) => {
          throw new Error(err);
        });
    }
  };

  const onDeleteRows = async (selectedRows) => {
    await dispatch(deleteItemsByIds(selectedRows));
    await loadData(0);
  };

  const controlClasses =
      'w-full rounded-xl border border-white/10 bg-white/5 px-3 py-2 text-sm text-slate-100 placeholder:text-slate-400 ' +
      ' ' + bgColor + ' ' + focusRing + ' ' + corners + ' ' +
      'dark:bg-slate-800/80 my-1';


  const dataGrid = (
        <div  className='relative overflow-x-auto'>
          <DataGrid
              autoHeight
              rowHeight={56}
              sx={dataGridStyles}
              className={'datagrid--table'}
              getRowClassName={() => `datagrid--row`}
              rows={booking_requests ?? []}
              columns={columns}
              initialState={{
                  pagination: {
                      paginationModel: {
                          pageSize: 10,
                      },
                  },
                  columns: {
                      columnVisibilityModel: compactColumnVisibilityModel,
                  },
              }}
              disableRowSelectionOnClick
              onProcessRowUpdateError={(params) => {
                  console.log('Error', params);
              }}
              processRowUpdate={async (newRow, oldRow) => {
                const data = dataFormatter.dataGridEditFormatter(newRow);

                try {
                  await handleTableSubmit(newRow.id, data);
                  return newRow;
                } catch {
                  return oldRow;
                }
              }}
              sortingMode={'server'}
              checkboxSelection
              onRowSelectionModelChange={(ids) => {
                setSelectedRows(ids)
              }}
              onSortModelChange={(params) => {
                  params.length
                      ? setSortModel(params)
                      : setSortModel([{ field: '', sort: 'desc' }]);
              }}
              rowCount={count}
              pageSizeOptions={[10]}
              paginationMode={'server'}
              loading={loading}
              onPaginationModelChange={(params) => {
                  onPageChange(params.page);
              }}
          />
        </div>
  )

  return (
    <>
    {filterItems && Array.isArray( filterItems ) && filterItems.length ?
        <CardBox className='mb-6 border border-white/10 shadow-none'>
            <Formik
                initialValues={{
                    checkboxes: ['lorem'],
                    switches: ['lorem'],
                    radio: 'lorem',
                }}
                onSubmit={() => null}
            >
                <Form>
                    <>
                        {filterItems && filterItems.map((filterItem) => {
                            return (
                                <div key={filterItem.id} className="mb-3 grid gap-3 rounded-2xl border border-white/10 bg-white/5 p-4 md:grid-cols-[minmax(0,1.1fr)_minmax(0,1fr)_auto]">
                                    <div className="flex min-w-0 flex-col">
                                        <div className="text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-400">Filter</div>
                                        <Field
                                            className={controlClasses}
                                            name='selectedField'
                                            id='selectedField'
                                            component='select'
                                            value={filterItem?.fields?.selectedField || ''}
                                            onChange={handleChange(filterItem.id)}
                                        >
                                            {filters.map((selectOption) => (
                                                <option
                                                    key={selectOption.title}
                                                    value={`${selectOption.title}`}
                                                >
                                                    {selectOption.label}
                                                </option>
                                            ))}
                                        </Field>
                                    </div>
                                    {filters.find((filter) => 
                                        filter.title === filterItem?.fields?.selectedField
                                    )?.type === 'enum' ? (
                                        <div className="flex min-w-0 flex-col">
                                            <div className="text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-400">
                                                Value
                                            </div>
                                            <Field
                                                className={controlClasses}
                                                name="filterValue"
                                                id='filterValue'
                                                component="select"
                                                value={filterItem?.fields?.filterValue || ''}
                                                onChange={handleChange(filterItem.id)}
                                            >
                                                <option value="">Select Value</option>
                                                {filters.find((filter) => 
                                                    filter.title === filterItem?.fields?.selectedField
                                                )?.options?.map((option) => (
                                                    <option key={option} value={option}>
                                                        {option}
                                                    </option>
                                                ))}
                                            </Field>
                                        </div>
                                    ) : filters.find((filter) => 
                                        filter.title === filterItem?.fields?.selectedField
                                    )?.number ? (
                                        <div className="grid min-w-0 gap-3 md:grid-cols-2">
                                            <div className="flex min-w-0 flex-col">
                                                <div className="text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-400">From</div>
                                                <Field
                                                    className={controlClasses}
                                                    name='filterValueFrom'
                                                    placeholder='From'
                                                    id='filterValueFrom'
                                                    value={filterItem?.fields?.filterValueFrom || ''}
                                                    onChange={handleChange(filterItem.id)}
                                                />
                                            </div>
                                            <div className="flex flex-col w-full">
                                                <div className="text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-400">To</div>
                                                <Field
                                                    className={controlClasses}
                                                    name='filterValueTo'
                                                    placeholder='to'
                                                    id='filterValueTo'
                                                    value={filterItem?.fields?.filterValueTo || ''}
                                                    onChange={handleChange(filterItem.id)}
                                                />
                                            </div>
                                        </div>
                                    ) : filters.find(
                                        (filter) =>
                                            filter.title ===
                                            filterItem?.fields?.selectedField
                                    )?.date ? (
                                        <div className='grid min-w-0 gap-3 md:grid-cols-2'>
                                            <div className='flex flex-col w-full mr-3'>
                                                <div className='text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-400'>
                                                    From
                                                </div>
                                                <Field
                                                    className={controlClasses}
                                                    name='filterValueFrom'
                                                    placeholder='From'
                                                    id='filterValueFrom'
                                                    type='datetime-local'
                                                    value={filterItem?.fields?.filterValueFrom || ''}
                                                    onChange={handleChange(filterItem.id)}
                                                />
                                            </div>
                                            <div className='flex flex-col w-full'>
                                                <div className='text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-400'>To</div>
                                                <Field
                                                    className={controlClasses}
                                                    name='filterValueTo'
                                                    placeholder='to'
                                                    id='filterValueTo'
                                                    type='datetime-local'
                                                    value={filterItem?.fields?.filterValueTo || ''}
                                                    onChange={handleChange(filterItem.id)}
                                                />
                                            </div>
                                        </div>
                                    ) : (
                                        <div className="flex min-w-0 flex-col">
                                            <div className="text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-400">Contains</div>
                                            <Field
                                                className={controlClasses}
                                                name='filterValue'
                                                placeholder='Contained'
                                                id='filterValue'
                                                value={filterItem?.fields?.filterValue || ''}
                                                onChange={handleChange(filterItem.id)}
                                            />
                                        </div>
                                    )}
                                    <div className="flex flex-col">
                                        <div className="text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-400">Action</div>
                                        <BaseButton
                                            className="my-1"
                                            type='reset'
                                            color='whiteDark'
                                            outline
                                            label='Delete'
                                            onClick={() => {
                                                deleteFilter(filterItem.id)
                                            }}
                                        />
                                    </div>
                                </div>
                            )
                        })}
                        <div className="flex flex-wrap items-center gap-2">
                            <BaseButton
                                className="my-1 mr-0"
                               type='submit' color='info'  
                                label='Apply'
                                onClick={handleSubmit}
                            />
                            <BaseButton
                                className="my-1"
                                 type='reset' color='whiteDark' outline  
                                label='Cancel'
                                onClick={handleReset}
                            />
                        </div>
                    </>
                </Form>
            </Formik>
        </CardBox> : null
    }
      <CardBoxModal
        title="Please confirm"
        buttonColor="info"
        buttonLabel={loading ? 'Deleting...' : 'Confirm'}
        isActive={isModalTrashActive}
        onConfirm={handleDeleteAction}
        onCancel={handleModalAction}
      >
        <p>Are you sure you want to delete this item?</p>
      </CardBoxModal>

      
      
      {!showGrid && kanbanColumns && (
        <>
          <div className='mb-6 grid gap-3 md:grid-cols-4'>
            {bookingKanbanOverview.map((item) => (
              <CardBox key={item.label} className='rounded-2xl border border-gray-200/80 shadow-none dark:border-dark-700'>
                <div className='p-4'>
                  <p className='text-xs font-semibold uppercase tracking-[0.18em] text-gray-400 dark:text-gray-500'>
                    {item.label}
                  </p>
                  <p className='mt-2 text-2xl font-semibold text-gray-900 dark:text-white'>
                    {item.value}
                  </p>
                  <p className='mt-1 text-sm text-gray-500 dark:text-gray-400'>{item.hint}</p>
                </div>
              </CardBox>
            ))}
          </div>
          <KanbanBoard
              columnFieldName={'status'}
              showFieldName={'request_code'}
              entityName={'booking_requests'}
              filtersQuery={kanbanFilters}
              deleteThunk={deleteItem}
              updateThunk={update}
              columns={kanbanColumns}
          />
        </>
        )}
      

      
        {showGrid && dataGrid}
      

      {selectedRows.length > 0 &&
        createPortal(
          <BaseButton
            className='me-4'
            color='danger'
            label={`Delete ${selectedRows.length === 1 ? 'Row' : 'Rows'}`}
            onClick={() => onDeleteRows(selectedRows)}
          />,
          document.getElementById('delete-rows-button'),
      )}
    <ToastContainer />
    </>
  )
}

export default TableSampleBooking_requests
