'use client';

import * as React from 'react';
import dynamic from 'next/dynamic';
import { zodResolver } from '@hookform/resolvers/zod';
import {
  Box,
  Button,
  FormControl,
  FormHelperText,
  IconButton,
  InputLabel,
  Modal,
  OutlinedInput,
  Stack,
  Typography,
  useTheme,
} from '@mui/material';
import { AppLoader } from '@/components/core/app-loader';
import { Close as CloseIcon } from '@mui/icons-material';
import { enqueueSnackbar } from 'notistack';
import { Controller, useForm } from 'react-hook-form';
import { z as zod } from 'zod';

import {
  createNewsletter,
  fetchNewsletterById,
  getApiErrorMessage,
  updateNewsletter,
} from '@/services/newsletter.service';
import { NewsletterReviewModal } from '@/components/dashboard/newsletter/newsletter-review-modal';

import 'react-quill/dist/quill.snow.css';

const ReactQuill = dynamic(() => import('react-quill'), { ssr: false });

const schema = zod.object({
  title: zod.string().min(1, 'Title is required'),
  subject: zod.string().min(1, 'Subject is required'),
  content: zod
    .string()
    .min(1, 'Content is required')
    .refine((value) => value.replace(/<(.|\n)*?>/g, '').trim().length > 0, {
      message: 'Content is required',
    }),
});

type FormValues = zod.infer<typeof schema>;

interface CreateNewsletterModalProps {
  open: boolean;
  onClose: () => void;
  onSuccess: () => void;
  newsletterId?: string | null;
}

const modalStyle = {
  position: 'absolute' as const,
  top: '50%',
  left: '50%',
  transform: 'translate(-50%, -50%)',
  width: '100%',
  maxWidth: 900,
  maxHeight: '90vh',
  bgcolor: 'background.paper',
  borderRadius: 4,
  boxShadow: 24,
  p: 4,
  overflowY: 'auto' as const,
};

const quillModules = {
  toolbar: [
    [{ header: [1, 2, 3, false] }],
    ['bold', 'italic', 'underline', 'strike'],
    [{ list: 'ordered' }, { list: 'bullet' }],
    ['link'],
    ['clean'],
  ],
};

const submitButtonSx = {
  bgcolor: 'rgba(11, 5, 4, 0.8)',
  color: '#FFDD31',
  '&:hover': { bgcolor: 'rgba(11, 5, 4, 0.9)' },
};

function buildDeliverySummary(
  recipientsCount?: number,
  emailsSent?: number,
  emailsFailed?: number
): string {
  if (!recipientsCount && !emailsSent) {
    return '';
  }

  const sent = emailsSent ?? 0;
  const total = recipientsCount ?? sent;
  const failed = emailsFailed ?? 0;

  return ` Sent to ${sent} of ${total} subscribers${failed > 0 ? ` (${failed} failed)` : ''}.`;
}

export function CreateNewsletterModal({
  open,
  onClose,
  onSuccess,
  newsletterId,
}: CreateNewsletterModalProps): React.JSX.Element {
  const theme = useTheme();
  const [isLoading, setIsLoading] = React.useState(false);
  const [isFetching, setIsFetching] = React.useState(false);
  const [reviewOpen, setReviewOpen] = React.useState(false);
  const [reviewValues, setReviewValues] = React.useState<FormValues | null>(null);
  const [reviewMode, setReviewMode] = React.useState<'create' | 'resend'>('create');
  const isEditMode = Boolean(newsletterId);

  const {
    control,
    handleSubmit,
    reset,
    formState: { errors },
  } = useForm<FormValues>({
    resolver: zodResolver(schema),
    defaultValues: {
      title: '',
      subject: '',
      content: '',
    },
  });

  React.useEffect(() => {
    if (!open) {
      return;
    }

    if (!newsletterId) {
      reset({ title: '', subject: '', content: '' });
      return;
    }

    const loadNewsletter = async () => {
      try {
        setIsFetching(true);
        const response = await fetchNewsletterById(newsletterId);
        const newsletter = response.data.newsletter;
        reset({
          title: newsletter.title,
          subject: newsletter.subject,
          content: newsletter.content,
        });
      } catch (error) {
        console.error('Error fetching newsletter:', error);
        enqueueSnackbar(getApiErrorMessage(error, 'Failed to load newsletter'), {
          variant: 'error',
        });
        onClose();
      } finally {
        setIsFetching(false);
      }
    };

    loadNewsletter();
  }, [open, newsletterId, reset, onClose]);

  const handleClose = () => {
    setReviewOpen(false);
    setReviewValues(null);
    reset({ title: '', subject: '', content: '' });
    onClose();
  };

  const openReview = (values: FormValues, mode: 'create' | 'resend') => {
    setReviewValues(values);
    setReviewMode(mode);
    setReviewOpen(true);
  };

  const closeReview = () => {
    setReviewOpen(false);
    setReviewValues(null);
  };

  const handleCreate = async (values: FormValues) => {
    const response = await createNewsletter({
      title: values.title,
      subject: values.subject,
      content: values.content,
    });

    const { recipientsCount, emailsSent, emailsFailed } = response.data;
    enqueueSnackbar(`${response.message}.${buildDeliverySummary(recipientsCount, emailsSent, emailsFailed)}`, {
      variant: emailsFailed && emailsFailed > 0 ? 'warning' : 'success',
    });
  };

  const handleUpdate = async (values: FormValues, resend: boolean) => {
    if (!newsletterId) {
      return;
    }

    const response = await updateNewsletter(newsletterId, {
      title: values.title,
      subject: values.subject,
      content: values.content,
      resend,
    });

    const { recipientsCount, emailsSent, emailsFailed } = response.data;
    const deliverySummary = resend
      ? buildDeliverySummary(recipientsCount, emailsSent, emailsFailed)
      : '';

    enqueueSnackbar(`${response.message}.${deliverySummary}`, {
      variant: resend && emailsFailed && emailsFailed > 0 ? 'warning' : 'success',
    });
  };

  const onSubmit = async (values: FormValues, resend = false) => {
    try {
      setIsLoading(true);

      if (isEditMode) {
        await handleUpdate(values, resend);
      } else {
        await handleCreate(values);
      }

      closeReview();
      handleClose();
      onSuccess();
    } catch (error) {
      console.error('Error saving newsletter:', error);
      enqueueSnackbar(
        getApiErrorMessage(error, isEditMode ? 'Failed to update newsletter' : 'Failed to create newsletter'),
        { variant: 'error' }
      );
    } finally {
      setIsLoading(false);
    }
  };

  const handleConfirmSend = () => {
    if (!reviewValues) {
      return;
    }

    onSubmit(reviewValues, reviewMode === 'resend');
  };

  return (
    <>
    <Modal open={open && !reviewOpen} onClose={handleClose}>
      <Box sx={modalStyle}>
        <Stack direction="row" justifyContent="space-between" alignItems="center" mb={3}>
          <Box>
            <Typography variant="h5" fontWeight={700}>
              {isEditMode ? 'Edit Newsletter' : 'Create Newsletter'}
            </Typography>
            <Typography variant="body2" color="text.secondary" sx={{ mt: 0.5 }}>
              {isEditMode
                ? 'Update the newsletter content. Save & Resend opens a review step before emailing subscribers.'
                : 'You will review title, subject, and content before the newsletter is sent.'}
            </Typography>
          </Box>
          <IconButton onClick={handleClose} disabled={isLoading || isFetching}>
            <CloseIcon />
          </IconButton>
        </Stack>

        {isFetching ? (
          <Box sx={{ position: 'relative', minHeight: 400 }}>
            <AppLoader fill size="lg" />
          </Box>
        ) : (
          <Box component="form">
            <Stack spacing={3}>
              <Controller
                name="title"
                control={control}
                render={({ field }) => (
                  <FormControl error={Boolean(errors.title)} fullWidth>
                    <InputLabel>Title</InputLabel>
                    <OutlinedInput {...field} label="Title" />
                    {errors.title && <FormHelperText>{errors.title.message}</FormHelperText>}
                  </FormControl>
                )}
              />

              <Controller
                name="subject"
                control={control}
                render={({ field }) => (
                  <FormControl error={Boolean(errors.subject)} fullWidth>
                    <InputLabel>Email Subject</InputLabel>
                    <OutlinedInput {...field} label="Email Subject" />
                    {errors.subject && <FormHelperText>{errors.subject.message}</FormHelperText>}
                  </FormControl>
                )}
              />

              <Box>
                <Typography variant="subtitle2" fontWeight={600} gutterBottom>
                  Content
                </Typography>
                <Controller
                  name="content"
                  control={control}
                  render={({ field }) => (
                    <Box
                      sx={{
                        '& .ql-container': {
                          minHeight: 200,
                          borderBottomLeftRadius: 8,
                          borderBottomRightRadius: 8,
                          bgcolor: theme.palette.background.paper,
                        },
                        '& .ql-toolbar': {
                          borderTopLeftRadius: 8,
                          borderTopRightRadius: 8,
                          bgcolor: theme.palette.mode === 'dark' ? '#2d3748' : '#f8fafc',
                        },
                        '& .ql-editor': {
                          minHeight: 200,
                        },
                      }}
                    >
                      <ReactQuill
                        theme="snow"
                        value={field.value}
                        onChange={field.onChange}
                        modules={quillModules}
                        placeholder="Write your newsletter content..."
                      />
                    </Box>
                  )}
                />
                {errors.content && (
                  <FormHelperText error sx={{ mt: 1 }}>
                    {errors.content.message}
                  </FormHelperText>
                )}
              </Box>

              <Stack direction="row" spacing={2} justifyContent="flex-end" pt={2}>
                <Button variant="outlined" onClick={handleClose} disabled={isLoading}>
                  Cancel
                </Button>
                {isEditMode ? (
                  <>
                    <Button
                      variant="contained"
                      disabled={isLoading}
                      sx={submitButtonSx}
                      onClick={handleSubmit((values) => onSubmit(values, false))}
                    >
                      {isLoading ? <AppLoader size="xs" inline color="#FFDD31" /> : 'Save Changes'}
                    </Button>
                    <Button
                      variant="contained"
                      disabled={isLoading}
                      sx={submitButtonSx}
                      onClick={handleSubmit((values) => openReview(values, 'resend'))}
                    >
                      Save & Resend
                    </Button>
                  </>
                ) : (
                  <Button
                    type="button"
                    variant="contained"
                    disabled={isLoading}
                    sx={submitButtonSx}
                    onClick={handleSubmit((values) => openReview(values, 'create'))}
                  >
                    Review & Send
                  </Button>
                )}
              </Stack>
            </Stack>
          </Box>
        )}
      </Box>
    </Modal>

    {reviewValues && (
      <NewsletterReviewModal
        open={reviewOpen}
        title={reviewValues.title}
        subject={reviewValues.subject}
        content={reviewValues.content}
        isLoading={isLoading}
        mode={reviewMode}
        onClose={closeReview}
        onBack={closeReview}
        onConfirm={handleConfirmSend}
      />
    )}
    </>
  );
}
