import { FC } from 'react';
import {
  useFormContext,
  Controller,
  UseControllerProps,
} from 'react-hook-form';

import Radio from '@material-hu/mui/Radio';
import Table from '@material-hu/mui/Table';
import TableBody from '@material-hu/mui/TableBody';
import TableCell from '@material-hu/mui/TableCell';
import TableContainer from '@material-hu/mui/TableContainer';
import TableHead from '@material-hu/mui/TableHead';
import TableRow from '@material-hu/mui/TableRow';

import { useRules, RulesOptions } from 'src/hooks/useRules';
import { Question, CheckboxGridValue } from 'src/types/forms';

export type CheckboxGridProps = Omit<UseControllerProps, 'rules'> &
  Partial<Question> & {
    disabled?: boolean;
    rules?: RulesOptions;
  };

export const CheckboxGrid: FC<CheckboxGridProps> = props => {
  const {
    name,
    defaultValue,
    options,
    rows,
    disabled = false,
    rules = {},
  } = props;

  const {
    control,
    setValue,
    watch,
    trigger,
    formState: { isSubmitted },
  } = useFormContext();

  const { requiredCheckboxGrid } = rules;
  const checkboxGridRules = useRules({
    ...rules,
    requiredCheckboxGrid: requiredCheckboxGrid && { rows, options },
  });

  const value: CheckboxGridValue = watch(name, defaultValue) || {};

  const isChecked = (row, option) =>
    !!value && !!value[row.id] && value[row.id][0] === option.description;

  const handleChange = (row, option) => {
    let newValue: CheckboxGridValue = { ...value };

    isChecked(row, option)
      ? delete newValue[row.id]
      : (newValue[row.id] = [option.description]);

    setValue(name, newValue);
    if (isSubmitted) {
      trigger(name);
    }
  };

  return (
    <Controller
      name={name}
      rules={checkboxGridRules}
      control={control}
      defaultValue={defaultValue}
      render={() => (
        <TableContainer>
          <Table>
            <TableHead>
              <TableRow>
                <TableCell align="center" />
                {options.map(option => (
                  <TableCell
                    key={option.id}
                    align="center"
                  >
                    {option.description}
                  </TableCell>
                ))}
              </TableRow>
            </TableHead>
            <TableBody>
              {rows.map(row => (
                <TableRow
                  key={row.id}
                  sx={{ '&:last-child td, &:last-child th': { border: 0 } }}
                >
                  <TableCell id={`row-${row.id}`}>{row.description}</TableCell>
                  {options.map(option => (
                    <TableCell
                      key={option.id}
                      align="center"
                    >
                      <Radio
                        value={option.description}
                        onClick={() => handleChange(row, option)}
                        disabled={disabled}
                        checked={isChecked(row, option)}
                        inputProps={{
                          'aria-label': option.description,
                        }}
                        sx={{
                          width: 'fit-content',
                        }}
                      />
                    </TableCell>
                  ))}
                </TableRow>
              ))}
            </TableBody>
          </Table>
        </TableContainer>
      )}
    />
  );
};

export default CheckboxGrid;
