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

function RsvpForm() {
  const [updateGuest, { isSuccess: success, isError: error }] =
    useUpdateGuestMutation();
  const guest: Guest = useOutletContext();
  const previousPartySize = useRef(guest?.partySize - 1);

  const {
    register,
    handleSubmit,
    control,
    watch,
    formState: { errors },
  } = useForm<Guest>({
    defaultValues: {
      id: guest?.id,
      firstName: guest?.firstName,
      lastName: guest?.lastName,
      attendance: guest?.attendance,
      email: guest?.email,
      message: guest?.message,
      partySize: guest?.partySize,
      partyList: guest?.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 (
    <form
      style={{
        height: '100%',
        width: '100%',
        display: 'flex',
        justifyContent: 'center',
        alignItems: 'start',
      }}
      noValidate
      onSubmit={handleSubmit(onSubmit)}
    >
      <Grid container spacing={2} sx={{ width: 600, mt: 16, mx: 0.5 }}>
        <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>
                  Attendance
                </FormLabel>
                <Controller
                  name="attendance"
                  control={control}
                  rules={{ required: true }}
                  render={({ field }) => (
                    <RadioGroup {...field} row>
                      <FormControlLabel
                        value="accept"
                        control={<Radio />}
                        label="Accept"
                      />
                      <FormControlLabel
                        value="decline"
                        control={<Radio />}
                        label="Decline"
                      />
                    </RadioGroup>
                  )}
                />
              </div>
            </FormControl>
          </div>
        </Grid>
        <Grid item xs={8}>
          <TextField
            label="Email"
            type="email"
            variant="outlined"
            fullWidth
            error={!!errors.email}
            helperText={errors.email?.message}
            required
            {...register('email', {
              setValueAs: (value: string) => value.trim(),
              required: 'This field is required',
              pattern: {
                value: /\S+@\S+\.\S+/,
                message: 'Please enter a valid email address',
              },
            })}
          />
        </Grid>
        <Grid item xs={4}>
          <TextField
            label="Party Size"
            type="number"
            variant="outlined"
            fullWidth
            onWheel={(event) => {
              event.currentTarget.blur();
            }}
            error={!!errors.partySize}
            helperText={errors.partySize?.message}
            required
            {...register('partySize', {
              valueAsNumber: true,
              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={6}>
                <TextField
                  label="First Name"
                  variant="outlined"
                  fullWidth
                  error={!!errors.partyList?.[index]?.firstName}
                  helperText={errors.partyList?.[index]?.firstName?.message}
                  required
                  {...register(`partyList.${index}.firstName`, {
                    setValueAs: (value: string) => value.trim(),
                    required: 'This field is required',
                  })}
                />
              </Grid>
              <Grid item xs={6}>
                <TextField
                  label="Last Name"
                  variant="outlined"
                  fullWidth
                  error={!!errors.partyList?.[index]?.lastName}
                  helperText={errors.partyList?.[index]?.lastName?.message}
                  required
                  {...register(`partyList.${index}.lastName`, {
                    setValueAs: (value: string) => value.trim(),
                    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>
          <div
            style={{ marginTop: 16, display: 'flex', justifyContent: 'center' }}
          >
            <div style={{ width: 180 }}>
              {success && <Alert severity="success">RSVP updated</Alert>}
              {error && <Alert severity="error">RSVP failed</Alert>}
            </div>
          </div>
        </Grid>
      </Grid>
    </form>
  );
}

export default RsvpForm;
