'use client';
import { useState } from 'react';
import { useLocale, useTranslations } from 'next-intl';
import { useParams, useRouter } from 'next/navigation';
import { useSnackbar } from 'notistack';
import {
  Box,
  Chip,
  Dialog,
  DialogActions,
  DialogContent,
  DialogTitle,
  Divider,
  Paper,
  Skeleton,
  Stack,
  TextField,
  Typography,
} from '@mui/material';
import { AppButton, AppIcon, CountdownTimer, PriceDisplay, StatusChip } from '@/components';
import { ROUTES } from '@/constants';
import { ApiError } from '@/lib/api/errors';
import { formatShamsiDate, localeTag } from '@/utils';
import {
  useAcceptBookingRequest,
  useBookingRequest,
  useRejectBookingRequest,
} from '@/services/bookingRequests';
import { REJECTION_REASON_MAX_LENGTH } from '@/services/bookingRequests/constants';
import { isTerminalBookingRequestStatus, type BookingRequestDto } from '@/services/bookingRequests/types';

/**
 * Nurse request detail (نمای پرستار). Renders the request summary and **only `customerNotes`** as the
 * clinical context (two-stage disclosure — the address is masked to city/district and no clinical field
 * exists pre-accept). A pending request offers accept / reject (with a reason); both invalidate the inbox
 * + this detail so the request leaves the pending list and the customer's C5 reflects it. A stale action
 * returns `409`, surfaced then refetched.
 */
export default function NurseRequestDetailPage() {
  const t = useTranslations('booking');
  const locale = useLocale();
  const router = useRouter();
  const { enqueueSnackbar } = useSnackbar();
  const params = useParams<{ id: string }>();
  const id = Number(params.id);

  const { data: request, isLoading, isError, refetch } = useBookingRequest(
    Number.isInteger(id) && id > 0 ? id : undefined,
    'nurse',
  );
  const acceptRequest = useAcceptBookingRequest();
  const rejectRequest = useRejectBookingRequest();

  const [rejectOpen, setRejectOpen] = useState(false);
  const [reason, setReason] = useState('');
  const [reasonError, setReasonError] = useState(false);

  if (isLoading) return <DetailSkeleton />;

  if (isError || !request) {
    return (
      <Paper elevation={0} sx={{ p: 4, textAlign: 'center', border: '1px solid', borderColor: 'divider', borderRadius: 2, maxWidth: 640 }}>
        <Typography variant="subtitle1" sx={{ fontWeight: 700, mb: 1 }}>
          {t('not_found_title')}
        </Typography>
        <Typography variant="body2" sx={{ color: 'text.secondary', mb: 2 }}>
          {t('not_found_body')}
        </Typography>
        <AppButton variant="outlined" color="primary" onClick={() => router.push(`/${locale}${ROUTES.NURSE_REQUESTS}`)}>
          {t('inbox_title')}
        </AppButton>
      </Paper>
    );
  }

  const pending = request.status === 'pending_nurse_response';
  const isTerminal = isTerminalBookingRequestStatus(request.status);
  const location = coarseLocation(request, locale, t('address_whole_city'));

  const handleStaleError = (error: unknown) => {
    if (error instanceof ApiError && error.status === 409) {
      enqueueSnackbar(t('action_stale'), { variant: 'warning' });
      refetch();
    } else {
      enqueueSnackbar(t('error_generic'), { variant: 'error' });
    }
  };

  const handleAccept = () => {
    acceptRequest.mutate(request.id, {
      onSuccess: () => enqueueSnackbar(t('accepted_toast'), { variant: 'success' }),
      onError: handleStaleError,
    });
  };

  const handleReject = () => {
    const trimmed = reason.trim();
    if (!trimmed) {
      setReasonError(true);
      return;
    }
    rejectRequest.mutate(
      { id: request.id, payload: { reason: trimmed } },
      {
        onSuccess: () => {
          setRejectOpen(false);
          setReason('');
          enqueueSnackbar(t('rejected_toast'), { variant: 'success' });
        },
        onError: (error) => {
          setRejectOpen(false);
          handleStaleError(error);
        },
      },
    );
  };

  const startDate = new Date(`${request.requestedDate}T${request.requestedTimeStart}`);
  const endDate = new Date(`${request.requestedDate}T${request.requestedTimeEnd}`);
  const timeFmt = new Intl.DateTimeFormat(localeTag(locale), { hour: '2-digit', minute: '2-digit' });
  const whenLabel = `${formatShamsiDate(startDate, locale)} · ${timeFmt.format(startDate)} – ${timeFmt.format(endDate)}`;

  return (
    <Box sx={{ display: 'flex', flexDirection: 'column', gap: 3, maxWidth: 640 }}>
      <Stack direction="row" sx={{ justifyContent: 'space-between', alignItems: 'center', gap: 2, flexWrap: 'wrap' }}>
        <Typography variant="h5" component="h1">
          {t('detail_title')}
        </Typography>
        <StatusChip status={statusKind(request.status)} label={t(`status_${request.status}`)} />
      </Stack>

      <Paper elevation={0} sx={{ p: 2.5, border: '1px solid', borderColor: 'divider', borderRadius: 2 }}>
        <Stack sx={{ gap: 1.5 }}>
          <DetailRow caption={t('summary_patient')}>
            <Typography variant="body2" sx={{ fontWeight: 500 }}>
              {request.patientName}
            </Typography>
          </DetailRow>
          <DetailRow caption={t('summary_service')}>
            <Stack sx={{ gap: 0.25, alignItems: 'flex-end' }}>
              <Typography variant="body2" sx={{ fontWeight: 500 }}>
                {request.variantLabel}
              </Typography>
              {request.variantPrice ? (
                <PriceDisplay price={request.variantPrice} priceUnit={request.variantPriceUnit} />
              ) : null}
            </Stack>
          </DetailRow>
          <DetailRow caption={t('location_label')}>
            <Typography variant="body2" sx={{ fontWeight: 500, textAlign: 'end' }}>
              {location}
            </Typography>
          </DetailRow>
          <DetailRow caption={t('summary_when')}>
            <Typography variant="body2" sx={{ fontWeight: 500, textAlign: 'end' }}>
              {whenLabel}
            </Typography>
          </DetailRow>
          {request.requiredCaregiverGender ? (
            <DetailRow caption={t('gender_label')}>
              <Chip
                size="small"
                label={t(`gender_${request.requiredCaregiverGender}`)}
                sx={{ bgcolor: 'var(--bal-primary-soft)', color: 'var(--bal-primary)', fontWeight: 500 }}
              />
            </DetailRow>
          ) : null}
        </Stack>
      </Paper>

      {/* Stage-1 clinical context — ONLY the family's notes, never a clinical/care field. */}
      <Paper elevation={0} sx={{ p: 2.5, border: '1px solid', borderColor: 'divider', borderRadius: 2 }}>
        <Stack sx={{ gap: 1 }}>
          <Typography variant="subtitle2" sx={{ fontWeight: 700 }}>
            {t('inbox_notes_label')}
          </Typography>
          <Typography variant="body2" sx={{ color: request.customerNotes ? 'text.primary' : 'text.secondary' }}>
            {request.customerNotes || '—'}
          </Typography>
          <Divider sx={{ my: 0.5 }} />
          <Stack direction="row" sx={{ gap: 1, alignItems: 'flex-start' }}>
            <AppIcon icon="info" size={18} color="var(--bal-info)" />
            <Typography variant="caption" sx={{ color: 'text.secondary' }}>
              {t('disclosure_note')}
            </Typography>
          </Stack>
        </Stack>
      </Paper>

      {pending ? (
        <Stack sx={{ gap: 1.5 }}>
          <CountdownTimer
            deadlineIso={request.nurseResponseDeadlineAt}
            label={t('response_countdown_label')}
            elapsedText={t('response_elapsed')}
            onElapsed={() => refetch()}
          />
          <Stack direction="row" sx={{ gap: 1 }}>
            <AppButton
              color="primary"
              variant="contained"
              startIcon="verified"
              disabled={acceptRequest.isPending}
              onClick={handleAccept}
              sx={{ flex: 1, py: 1.25 }}
            >
              {acceptRequest.isPending ? t('accepting') : t('accept')}
            </AppButton>
            <AppButton
              color="error"
              variant="outlined"
              startIcon="rejected"
              disabled={acceptRequest.isPending}
              onClick={() => setRejectOpen(true)}
              sx={{ flex: 1, py: 1.25 }}
            >
              {t('reject')}
            </AppButton>
          </Stack>
        </Stack>
      ) : (
        <Paper
          elevation={0}
          sx={{
            p: 2,
            borderRadius: 2,
            border: '1px solid',
            borderColor: 'divider',
            borderInlineStartWidth: 4,
            borderInlineStartColor: isTerminal ? 'var(--bal-text-secondary)' : 'var(--bal-secondary)',
          }}
        >
          <Typography variant="body2" sx={{ color: 'text.secondary' }}>
            {t(`status_${request.status}`)}
          </Typography>
        </Paper>
      )}

      <Dialog open={rejectOpen} onClose={() => setRejectOpen(false)} fullWidth maxWidth="xs">
        <DialogTitle>{t('reject_dialog_title')}</DialogTitle>
        <DialogContent>
          <TextField
            autoFocus
            label={t('reject_reason_label')}
            placeholder={t('reject_reason_placeholder')}
            value={reason}
            onChange={(event) => {
              setReason(event.target.value.slice(0, REJECTION_REASON_MAX_LENGTH));
              if (reasonError) setReasonError(false);
            }}
            error={reasonError}
            helperText={reasonError ? t('reason_required') : undefined}
            multiline
            minRows={2}
            fullWidth
            sx={{ mt: 1 }}
          />
        </DialogContent>
        <DialogActions>
          <AppButton variant="text" onClick={() => setRejectOpen(false)}>
            {t('cancel_request')}
          </AppButton>
          <AppButton color="error" variant="contained" disabled={rejectRequest.isPending} onClick={handleReject}>
            {rejectRequest.isPending ? t('rejecting') : t('reject_submit')}
          </AppButton>
        </DialogActions>
      </Dialog>
    </Box>
  );
}

/** Coarse, masked location (city · district) — the nurse view never receives the full address. */
function coarseLocation(request: BookingRequestDto, locale: string, wholeCityLabel: string): string {
  const city = locale === 'en' ? request.cityNameEn : request.cityNameFa;
  const district =
    request.districtId == null ? wholeCityLabel : locale === 'en' ? request.districtNameEn : request.districtNameFa;
  return `${city} · ${district}`;
}

function statusKind(status: BookingRequestDto['status']) {
  switch (status) {
    case 'accepted_awaiting_payment':
      return 'active' as const;
    case 'converted':
      return 'verified' as const;
    case 'rejected_by_nurse':
    case 'payment_deadline_expired':
      return 'rejected' as const;
    case 'expired_no_response':
    case 'cancelled_by_customer':
      return 'neutral' as const;
    default:
      return 'pending' as const;
  }
}

function DetailRow({ caption, children }: { caption: string; children: React.ReactNode }) {
  return (
    <Stack direction="row" sx={{ gap: 2, justifyContent: 'space-between', alignItems: 'flex-start' }}>
      <Typography variant="body2" sx={{ color: 'text.secondary', flexShrink: 0 }}>
        {caption}
      </Typography>
      {children}
    </Stack>
  );
}

function DetailSkeleton() {
  return (
    <Box sx={{ display: 'flex', flexDirection: 'column', gap: 3, maxWidth: 640 }}>
      <Skeleton variant="text" width="40%" height={36} />
      <Skeleton variant="rounded" height={180} />
      <Skeleton variant="rounded" height={120} />
      <Skeleton variant="rounded" height={56} />
    </Box>
  );
}
