/**
 * Page Elements Table Component
 */

import React, { useEffect, useState, useMemo } from 'react';
import { ToastContainer, toast } from 'react-toastify';
import CardBox from '../CardBox';
import BaseButton from '../BaseButton';
import GenericTable from '../Generic/GenericTable';
import KanbanBoard from '../KanbanBoard/KanbanBoard';
import {
  fetch,
  update,
  deleteItem,
  setRefetch,
  deleteItemsByIds,
} from '../../stores/page_elements/page_elementsSlice';
import { loadColumns } from './configurePage_elementsCols';
import { useAppSelector } from '../../stores/hooks';
import { Field, Form, Formik } from 'formik';
import type { PageElement } from '../../types/entities';
import type { RootState } from '../../stores/store';
import type { Filter, FilterItem } from '../../types/filters';

interface TablePage_elementsProps {
  filterItems: FilterItem[];
  setFilterItems: (items: FilterItem[]) => void;
  filters: Filter[];
  showGrid?: boolean;
  extraQuery?: string;
}

const KANBAN_COLUMNS = [
  { id: 'nav_button', label: 'nav_button' },
  { id: 'spot', label: 'spot' },
  { id: 'description', label: 'description' },
  { id: 'tooltip', label: 'tooltip' },
  { id: 'gallery', label: 'gallery' },
  { id: 'carousel', label: 'carousel' },
  { id: 'logo', label: 'logo' },
  { id: 'video_player', label: 'video_player' },
  { id: 'popup', label: 'popup' },
];

const TablePage_elements: React.FC<TablePage_elementsProps> = ({
  filterItems,
  setFilterItems,
  filters,
  showGrid = false,
  extraQuery = '',
}) => {
  const [kanbanFilters, setKanbanFilters] = useState('');
  const focusRing = useAppSelector((state) => state.style.focusRingColor);
  const bgColor = useAppSelector((state) => state.style.bgLayoutColor);
  const corners = useAppSelector((state) => state.style.corners);

  const controlClasses =
    'w-full py-2 px-2 my-2 rounded dark:placeholder-gray-400 ' +
    ` ${bgColor} ${focusRing} ${corners} ` +
    'dark:bg-slate-800 border';

  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 handleChange =
    (id: string) =>
    (e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement>) => {
      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: {
                selectedField: value,
                filterValue: '',
                filterValueFrom: '',
                filterValueTo: '',
              },
            };
          return { id, fields: { ...item.fields, [name]: value } };
        }),
      );
    };

  const deleteFilter = (value: string) => {
    const newItems = filterItems.filter((item) => item.id !== value);
    if (!newItems.length) {
      setKanbanFilters('');
    }
    setFilterItems(newItems);
  };

  const handleSubmit = () => {
    setKanbanFilters(generateFilterRequests);
  };

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

  // Show grid view using GenericTable
  if (showGrid) {
    return (
      <GenericTable<PageElement>
        entityName='page_elements'
        sliceSelector={(state: RootState) => state.page_elements}
        fetchAction={fetch}
        updateAction={update}
        deleteAction={deleteItem}
        deleteByIdsAction={deleteItemsByIds}
        setRefetchAction={setRefetch}
        loadColumnsFunction={loadColumns}
        filters={filters}
        filterItems={filterItems}
        setFilterItems={setFilterItems}
        extraQuery={extraQuery}
      />
    );
  }

  // Show kanban view with custom filter handling
  return (
    <>
      {filterItems && Array.isArray(filterItems) && filterItems.length > 0 && (
        <CardBox>
          <Formik
            initialValues={{
              checkboxes: ['lorem'],
              switches: ['lorem'],
              radio: 'lorem',
            }}
            onSubmit={() => null}
          >
            <Form>
              {filterItems.map((filterItem) => (
                <div key={filterItem.id} className='flex mb-4'>
                  <div className='flex flex-col w-full mr-3'>
                    <div className='text-gray-500 font-bold'>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(
                    (f) => f.title === filterItem?.fields?.selectedField,
                  )?.type === 'enum' ? (
                    <div className='flex flex-col w-full mr-3'>
                      <div className='text-gray-500 font-bold'>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(
                            (f) =>
                              f.title === filterItem?.fields?.selectedField,
                          )
                          ?.options?.map((option) => (
                            <option key={option} value={option}>
                              {option}
                            </option>
                          ))}
                      </Field>
                    </div>
                  ) : (
                    <div className='flex flex-col w-full mr-3'>
                      <div className='text-gray-500 font-bold'>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-gray-500 font-bold'>Action</div>
                    <BaseButton
                      className='my-2'
                      type='reset'
                      color='danger'
                      label='Delete'
                      onClick={() => deleteFilter(filterItem.id)}
                    />
                  </div>
                </div>
              ))}
              <div className='flex'>
                <BaseButton
                  className='my-2 mr-3'
                  color='success'
                  label='Apply'
                  onClick={handleSubmit}
                />
                <BaseButton
                  className='my-2'
                  color='info'
                  label='Cancel'
                  onClick={handleReset}
                />
              </div>
            </Form>
          </Formik>
        </CardBox>
      )}
      <KanbanBoard
        columnFieldName='element_type'
        showFieldName='name'
        entityName='page_elements'
        filtersQuery={kanbanFilters}
        deleteThunk={deleteItem}
        updateThunk={update}
        columns={KANBAN_COLUMNS}
      />
      <ToastContainer />
    </>
  );
};

export default TablePage_elements;
