'use client';
import { FunctionComponent, useState } from 'react';
import Dialog from '@mui/material/Dialog';
import DialogTitle from '@mui/material/DialogTitle';
import DialogContent from '@mui/material/DialogContent';
import DialogActions from '@mui/material/DialogActions';
import MenuItem from '@mui/material/MenuItem';
import Stack from '@mui/material/Stack';
import Typography from '@mui/material/Typography';
import { useLocale, useTranslations } from 'next-intl';
import { useRouter } from 'next/navigation';
import { FormProvider, useForm, useWatch } from 'react-hook-form';
import AppButton from '@/components/common/AppButton';
import { AppIcon } from '@/components/common';
import { RhfTextField } from '@/components/common/form';
import { ticketThreadPath } from '@/constants';
import { useOpenTicket } from '@/services/tickets';
import type { OpenTicketResult, TicketCategory } from '@/services/tickets/types';

interface TicketDraft {
  category: TicketCategory;
  subject: string;
  body: string;
}

export interface ContactSupportDialogProps {
  open: boolean;
  onClose: () => void;
  /** Which shell to route the new thread into on success. */
  role: 'customer' | 'nurse';
  /** Pre-link the ticket to a booking (from the booking-detail entry point). */
  bookingId?: number | null;
  /** Initial category — `coordination` from a booking, else `support`. */
  defaultCategory?: TicketCategory;
}

/** Categories a user may open directly (refund is staff-linked; emergency uses its own flow). */
const OPENABLE_CATEGORIES: TicketCategory[] = ['support', 'coordination'];

/**
 * The "Contact support" flow — open a new ticket (category select → subject/message → submit) and, on
 * success, show the new **`referenceCode`** with a link to the thread. Used from the inbox and the
 * booking-detail entry point (pre-linked to a `bookingId`; the mock's coordination idempotency **jumps to the
 * existing coordination thread** rather than duplicating). Domain 4xx keep the draft (never cleared on
 * failure). On success the inbox is invalidated, so the new ticket appears at the top without a manual refresh.
 * @component ContactSupportDialog
 */
const ContactSupportDialog: FunctionComponent<ContactSupportDialogProps> = ({
  open,
  onClose,
  role,
  bookingId,
  defaultCategory = 'support',
}) => {
  const t = useTranslations('tickets');
  const locale = useLocale();
  const router = useRouter();
  const openTicket = useOpenTicket();

  const [created, setCreated] = useState<OpenTicketResult | null>(null);
  const form = useForm<TicketDraft>({
    mode: 'onTouched',
    defaultValues: { category: defaultCategory, subject: '', body: '' },
  });
  const { control, handleSubmit } = form;
  const body = useWatch({ control, name: 'body' });

  const handleClose = () => {
    form.reset({ category: defaultCategory, subject: '', body: '' });
    setCreated(null);
    openTicket.reset();
    onClose();
  };

  const submit = (draft: TicketDraft) => {
    if (openTicket.isPending) return;
    openTicket.mutate(
      {
        category: draft.category,
        subject: draft.subject.trim() || null,
        body: draft.body.trim(),
        bookingId: bookingId ?? null,
      },
      { onSuccess: (result) => setCreated(result) },
    );
  };

  const goToThread = () => {
    if (!created) return;
    router.push(`/${locale}${ticketThreadPath(role, created.ticketId)}`);
    handleClose();
  };

  return (
    <Dialog open={open} onClose={handleClose} fullWidth maxWidth="sm">
      {created ? (
        <>
          <DialogTitle sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
            <AppIcon icon="verified" size={22} color="var(--bal-success)" />
            {t('created_title')}
          </DialogTitle>
          <DialogContent>
            <Stack sx={{ gap: 1 }}>
              <Typography variant="body2" sx={{ color: 'var(--bal-text-secondary)' }}>
                {t('created_body')}
              </Typography>
              <Stack direction="row" sx={{ gap: 1, alignItems: 'center' }}>
                <Typography variant="caption" sx={{ color: 'var(--bal-text-secondary)' }}>
                  {t('ref_code_label')}
                </Typography>
                <Typography variant="subtitle1" sx={{ fontWeight: 800, letterSpacing: 0.5, direction: 'ltr' }}>
                  {created.referenceCode}
                </Typography>
              </Stack>
            </Stack>
          </DialogContent>
          <DialogActions>
            <AppButton variant="text" color="primary" onClick={handleClose}>
              {t('close')}
            </AppButton>
            <AppButton variant="contained" color="primary" onClick={goToThread}>
              {t('view_thread')}
            </AppButton>
          </DialogActions>
        </>
      ) : (
        <FormProvider {...form}>
          <DialogTitle>{t('new_ticket_title')}</DialogTitle>
          <DialogContent>
            {/* A real <form> so Enter submits from any field; the footer button (outside DialogContent)
                calls the same handler directly rather than relying on cross-element form association. */}
            <Stack component="form" noValidate onSubmit={handleSubmit(submit)} sx={{ gap: 2, pt: 1 }}>
              <RhfTextField<TicketDraft> name="category" select label={t('category_label')} fullWidth size="small">
                {OPENABLE_CATEGORIES.map((code) => (
                  <MenuItem key={code} value={code}>
                    {t(`category_${code}`)}
                  </MenuItem>
                ))}
              </RhfTextField>
              <RhfTextField<TicketDraft> name="subject" label={t('subject_label')} fullWidth size="small" />
              <RhfTextField<TicketDraft>
                name="body"
                label={t('message_label')}
                rules={{ validate: (value) => String(value ?? '').trim().length > 0 || t('message_required') }}
                fullWidth
                required
                multiline
                minRows={3}
                size="small"
              />
              {openTicket.isError ? (
                <Typography variant="caption" sx={{ color: 'var(--bal-error)' }}>
                  {t('open_failed')}
                </Typography>
              ) : null}
            </Stack>
          </DialogContent>
          <DialogActions>
            <AppButton variant="text" color="primary" onClick={handleClose}>
              {t('cancel')}
            </AppButton>
            <AppButton
              variant="contained"
              color="primary"
              onClick={handleSubmit(submit)}
              disabled={openTicket.isPending || body.trim().length === 0}
            >
              {openTicket.isPending ? t('submitting') : t('submit')}
            </AppButton>
          </DialogActions>
        </FormProvider>
      )}
    </Dialog>
  );
};

export default ContactSupportDialog;
