import React from 'react';
import { useRef } from 'react';
import { useOutletContext } from 'react-router-dom';
import {
  Button,
  Container,
  FormControl,
  FormControlLabel,
  FormLabel,
  Grid,
  Radio,
  RadioGroup,
  TextField,
} from '@mui/material';
import { useForm, Controller, useFieldArray } from 'react-hook-form';
import { useUpdateGuestMutation } from '../apiSlice';
import type { Guest } from '../apiSlice';

type FormValues = {
  id: number;
  firstName: string;
  lastName: string;
  attendance: string;
  email: string;
  partySize: number;
  message: string;
  partyList: {
    firstName: string;
    lastName: string;
  }[];
};

function RsvpForm() {
  const [updateGuest] = useUpdateGuestMutation();
  const guest: Guest = useOutletContext();
  const previousPartySize = useRef(0);

  const {
    register,
    handleSubmit,
    control,
    watch,
    formState: { errors },
  } = useForm<FormValues>({
    defaultValues: {
      id: guest?.id,
      firstName: guest?.firstName,
      lastName: guest?.lastName,
      attendance: '',
      email: '',
      message: '',
      partySize: 1,
      partyList: [],
    },
  });

  const onSubmit = async (data: Guest) => {
    updateGuest({ ...data });
  };

  const { fields, append, remove } = useFieldArray({
    control,
    name: 'partyList',
  });

  const handleParty = () => {
    const partySize = Number(watch('partySize')) - 1;
    if (
      partySize > previousPartySize.current &&
      partySize > 0 &&
      partySize < 10
    ) {
      append(
        new Array(partySize - previousPartySize.current).fill({
          firstName: '',
          lastName: '',
        })
      );
      previousPartySize.current = partySize;
    } else if (partySize < previousPartySize.current && partySize >= 0) {
      remove(
        [...Array(previousPartySize.current - partySize).keys()].map(
          (_, i) => partySize - 1 + i
        )
      );
      previousPartySize.current = partySize;
    }
  };

  return (
    <Container
      component="form"
      maxWidth="sm"
      noValidate
      onSubmit={handleSubmit(onSubmit)}
    >
      <Grid container spacing={2} sx={{ mt: 8 }}>
        <Grid item xs={12}>
          <p>
            Please RSVP for the wedding by March 10, 2025. The ceremony will
            commence at 3 PM on April 26 in Divine Shepherd. The reception will
            follow at 5 PM in A Venue on the Ridge.
          </p>
        </Grid>
        <Grid item xs={12}>
          <div style={{ display: 'flex', justifyContent: 'center' }}>
            <FormControl>
              <div style={{ display: 'flex', alignItems: 'center' }}>
                <FormLabel sx={{ mr: 2 }} error={!!errors.attendance} required>
                  Will you attend?
                </FormLabel>
                <Controller
                  name="attendance"
                  control={control}
                  rules={{ required: true }}
                  render={({ field }) => (
                    <RadioGroup {...field} row>
                      <FormControlLabel
                        value="yes"
                        control={<Radio />}
                        label="Yes"
                      />
                      <FormControlLabel
                        value="no"
                        control={<Radio />}
                        label="No"
                      />
                    </RadioGroup>
                  )}
                />
              </div>
            </FormControl>
          </div>
        </Grid>
        <Grid item xs={12} md={6} lg={6}>
          <TextField
            label="Email"
            type="email"
            variant="outlined"
            fullWidth
            error={!!errors.email}
            helperText={errors.email?.message}
            required
            {...register('email', {
              required: 'This field is required',
              pattern: {
                value: /\S+@\S+\.\S+/,
                message: 'Please enter a valid email address',
              },
            })}
          />
        </Grid>
        <Grid item xs={12} md={6} lg={6}>
          <TextField
            label="Party Size"
            type="number"
            variant="outlined"
            fullWidth
            onWheel={(event) => {
              event.currentTarget.blur();
            }}
            error={!!errors.partySize}
            helperText={errors.partySize?.message}
            required
            {...register('partySize', {
              onChange: handleParty,
              required: 'This field is required',
              min: { value: 1, message: 'Please enter a positive integer' },
              max: {
                value: 9,
                message: 'Please enter an integer less than 10',
              },
            })}
          />
        </Grid>
        <Grid item xs={12}>
          <TextField
            label="Message to the couple"
            variant="outlined"
            fullWidth
            multiline
            rows={3}
            {...register('message')}
          />
        </Grid>
        {fields.map((field, index) => {
          return (
            <Grid
              container
              item
              columnSpacing={2}
              rowSpacing={{ xs: 1 }}
              key={field.id}
            >
              <Grid item xs={12} md={6} lg={6}>
                <TextField
                  label="First Name"
                  variant="outlined"
                  fullWidth
                  error={!!errors.partyList?.[index]?.firstName}
                  helperText={errors.partyList?.[index]?.firstName?.message}
                  required
                  {...register(`partyList.${index}.firstName`, {
                    required: 'This field is required',
                  })}
                />
              </Grid>
              <Grid item xs={12} md={6} lg={6}>
                <TextField
                  label="Last Name"
                  variant="outlined"
                  fullWidth
                  error={!!errors.partyList?.[index]?.lastName}
                  helperText={errors.partyList?.[index]?.lastName?.message}
                  required
                  {...register(`partyList.${index}.lastName`, {
                    required: 'This field is required',
                  })}
                />
              </Grid>
            </Grid>
          );
        })}
        <Grid item xs={12}>
          <div
            style={{
              display: 'flex',
              flexDirection: 'column',
              alignItems: 'center',
            }}
          >
            <Button type="submit" variant="contained">
              RSVP
            </Button>
          </div>
        </Grid>
      </Grid>
    </Container>
  );
}

export default RsvpForm;
