'use client';

import { useEffect, useMemo, useState } from 'react';

import { useTranslations } from 'next-intl';

import { zodResolver } from '@hookform/resolvers/zod';
import { Send } from 'lucide-react';
import { useForm, useWatch } from 'react-hook-form';

import TurnstileWidget from '@/components/TurnstileWidget';
import { Button } from '@/components/ui/button';
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogHeader,
  DialogTitle,
} from '@/components/ui/dialog';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Textarea } from '@/components/ui/textarea';
import { useToast } from '@/hooks/use-toast';
import {
  createUserMessageFormSchema,
  MAX_USER_MESSAGE_LENGTH,
  UserMessageFormValues,
} from '@/lib/schemas/userMessageFormSchema';

import { UserMessageType } from '@/services/userMessages';

import { Link } from '@/i18n/navigation';

interface ContributeDialogProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  /** identifier of the record the message is attached to (creation azonosító) */
  rowId: number | string;
  /** message bucket on the backend */
  messageType?: UserMessageType;
}

const ContributeDialog: React.FC<ContributeDialogProps> = ({
  open,
  onOpenChange,
  rowId,
  messageType = 'alkotas',
}) => {
  const t = useTranslations('contribute.dialog');
  const tValidation = useTranslations('contribute.validation');
  const tToast = useTranslations('contribute.toast');
  const { toast } = useToast();
  const [turnstileToken, setTurnstileToken] = useState('');

  const schema = useMemo(() => createUserMessageFormSchema(tValidation), [tValidation]);

  const {
    register,
    handleSubmit,
    reset,
    control,
    formState: { errors, isSubmitting },
  } = useForm<UserMessageFormValues>({
    resolver: zodResolver(schema),
    defaultValues: { email: '', message: '' },
    mode: 'onChange',
  });

  // reset the form (and the captcha token) whenever the dialog is closed
  useEffect(() => {
    if (!open) {
      reset();
      setTurnstileToken('');
    }
  }, [open, reset]);

  const messageValue = useWatch({ control, name: 'message' });
  const messageLength = messageValue?.length ?? 0;

  const onSubmit = async (values: UserMessageFormValues) => {
    if (!turnstileToken) {
      toast({
        variant: 'destructive',
        title: tToast('captchaMissingTitle'),
        description: tToast('captchaMissingMessage'),
      });
      return;
    }

    try {
      const response = await fetch('/api/submit-user-message', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          dto: {
            rowId,
            messageType,
            email: values.email,
            message: values.message,
          },
          turnstileToken,
        }),
      });

      const data = await response.json();

      if (response.ok && data.success) {
        toast({
          variant: 'success',
          title: tToast('successTitle'),
          description: tToast('successMessage'),
        });
        onOpenChange(false);
      } else {
        toast({
          variant: 'destructive',
          title: tToast('errorTitle'),
          description: tToast('errorMessage'),
        });
      }
    } catch (error) {
      console.error('User message submit error:', error);
      toast({
        variant: 'destructive',
        title: tToast('errorTitle'),
        description: tToast('errorMessage'),
      });
    }
  };

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="max-w-lg">
        <DialogHeader>
          <DialogTitle>{t('title')}</DialogTitle>
          <DialogDescription>{t('description')}</DialogDescription>
        </DialogHeader>

        <form onSubmit={handleSubmit(onSubmit)} className="grid gap-5">
          <div className="grid gap-1.5">
            <Label htmlFor="contribute-email">{t('emailLabel')}</Label>
            <Input
              id="contribute-email"
              type="email"
              autoComplete="email"
              placeholder={t('emailPlaceholder')}
              aria-invalid={!!errors.email}
              {...register('email')}
            />
            {errors.email && <p className="text-xs text-red-600">{errors.email.message}</p>}
          </div>

          <div className="grid gap-1.5">
            <Label htmlFor="contribute-message">{t('messageLabel')}</Label>
            <Textarea
              id="contribute-message"
              rows={5}
              placeholder={t('messagePlaceholder')}
              aria-invalid={!!errors.message}
              {...register('message')}
            />
            <div className="flex items-center justify-between">
              {errors.message ? (
                <p className="text-xs text-red-600">{errors.message.message}</p>
              ) : (
                <span />
              )}
              <span className="text-xs text-muted-foreground">
                {messageLength} / {MAX_USER_MESSAGE_LENGTH}
              </span>
            </div>
          </div>

          <TurnstileWidget onToken={setTurnstileToken} />

          <p className="text-xs leading-relaxed text-muted-foreground">
            {t.rich('privacyNotice', {
              privacyLink: (chunks) => (
                <Link href="/adatkezelesi-tajekoztato" className="underline underline-offset-2">
                  {chunks}
                </Link>
              ),
            })}
          </p>

          <div className="flex flex-col-reverse gap-2 sm:flex-row sm:justify-end">
            <Button type="button" variant="quiet" onClick={() => onOpenChange(false)}>
              {t('cancel')}
            </Button>
            <Button type="submit" disabled={isSubmitting} className="gap-2">
              {isSubmitting ? t('submitting') : t('submit')}
              <Send className="size-4" />
            </Button>
          </div>
        </form>
      </DialogContent>
    </Dialog>
  );
};

export default ContributeDialog;
