import React, { PropsWithChildren, useCallback } from 'react';
import { useFieldArray } from 'react-hook-form';
import { FormGroup, useFormGroupName } from 'react-compose-form';
import { ArrowDown, ArrowUp, Plus, Trash } from 'lucide-react';
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger
} from '@/components/ui/dropdown-menu';
import { Button } from '@/components/ui/button';
import {
  PollQuestion,
  CreatePollQuestion
} from '@/server/modules/poll/types/poll-question.type';
import { PollQuestionType } from '@/server/modules/poll/types/poll-question-type.enum';
import { InputControl } from '@/components/form/control/input.control';
import { PollQuestionOptionCollection } from '@/components/form/control/poll-question-option.collection';
import { FormLabel } from '@/components/form/form-label';
import { FormMessage } from '@/components/form/form-message';
import { Card, CardContent } from '@/components/ui/card';

type PollQuestionCollectionProps = PropsWithChildren<{
  label?: string;
  name: string;
}>;

export const PollQuestionCollection: React.FC<PollQuestionCollectionProps> = (
  props
) => {
  const { label, name } = props;

  const fullName = useFormGroupName(name);

  const { append, remove, fields, move } = useFieldArray<
    {
      [key: typeof fullName]: Omit<CreatePollQuestion, 'pollId' | 'stat'>[];
    },
    string,
    '_key'
  >({
    name: fullName,
    keyName: '_key'
  });

  const handleAddQuestion = useCallback(
    (type: PollQuestionType) => {
      append({
        title: '',
        type,
        params: ((): PollQuestion['params'] => {
          switch (type) {
            case PollQuestionType.RADIO:
            case PollQuestionType.CHECKBOX:
              return {
                options: []
              };

            case PollQuestionType.SLIDER:
              return {
                min: 1,
                max: 10,
                step: 1
              };

            case PollQuestionType.TEXTAREA:
              return {};
          }
        })()
      });
    },
    [append]
  );

  return (
    <div className='flex flex-col gap-2'>
      <div className='flex items-end justify-between'>
        <div>{label && <FormLabel name={name}>{label}</FormLabel>}</div>

        <DropdownMenu>
          <DropdownMenuTrigger className='flex'>
            <Plus /> Add question
          </DropdownMenuTrigger>

          <DropdownMenuContent>
            {Object.entries(PollQuestionType).map(([key, type]) => {
              return (
                <DropdownMenuItem
                  key={type}
                  onClick={() => handleAddQuestion(type)}
                >
                  {key}
                </DropdownMenuItem>
              );
            })}
          </DropdownMenuContent>
        </DropdownMenu>
      </div>

      <div className='flex flex-col gap-2'>
        {fields.map((field, index) => {
          return (
            <FormGroup key={field._key} name={`${name}.${index}`}>
              <Card>
                <CardContent>
                  <div className='flex flex-col gap-2'>
                    <div className='flex items-center justify-between gap-2'>
                      <p>
                        Field type: <b>{field.type}</b>
                      </p>
                      <div className='flex gap-1'>
                        <Button
                          type='button'
                          size='icon'
                          variant='outline'
                          disabled={index === 0}
                          onClick={() => move(index, index - 1)}
                        >
                          <ArrowUp />
                        </Button>
                        <Button
                          type='button'
                          size='icon'
                          variant='outline'
                          disabled={index === fields.length - 1}
                          onClick={() => move(index, index + 1)}
                        >
                          <ArrowDown />
                        </Button>
                      </div>
                    </div>
                    <div className='flex gap-2'>
                      <div className='flex-1'>
                        <InputControl label='Title' name='title' />
                      </div>

                      <Button
                        className='mt-5'
                        type='button'
                        size='icon'
                        variant='destructive'
                        onClick={() => remove(index)}
                      >
                        <Trash />
                      </Button>
                    </div>

                    {[
                      PollQuestionType.CHECKBOX,
                      PollQuestionType.RADIO
                    ].includes(field.type) && (
                      <PollQuestionOptionCollection
                        label='Options'
                        name='params.options'
                      />
                    )}

                    {field.type === PollQuestionType.SLIDER && (
                      <div className='flex flex-row items-start gap-2'>
                        <div className='flex-1'>
                          <InputControl
                            type='number'
                            label='Min'
                            name='params.min'
                          />
                        </div>

                        <div className='flex-1'>
                          <InputControl
                            type='number'
                            label='Max'
                            name='params.max'
                          />
                        </div>

                        <div className='flex-1'>
                          <InputControl
                            type='number'
                            label='Step'
                            name='params.step'
                          />
                        </div>
                      </div>
                    )}

                    <FormMessage name='params' />
                  </div>
                </CardContent>
              </Card>

              <InputControl type='hidden' name='id' />
              <InputControl type='hidden' name='type' />
            </FormGroup>
          );
        })}
      </div>

      <FormMessage name={fullName} />
    </div>
  );
};
