'use client';
import { useState } from 'react';
import { useLocale, useTranslations } from 'next-intl';
import { useParams, useRouter } from 'next/navigation';
import { Paper, Skeleton, Stack, Typography } from '@mui/material';
import {
  AppButton,
  AppIcon,
  BookingRequestSummaryCard,
  ConfirmDialog,
  CountdownTimer,
  StatusChip,
  StepperHeader,
} from '@/components';
import { ROUTES } from '@/constants';
import { useBookingRequest, useCancelBookingRequest } from '@/services/bookingRequests';
import type { BookingRequestDto } from '@/services/bookingRequests/types';

const MINUTES_PER_HOUR = 60;

/** Freeform-text heuristic (the DTO carries no structured rejection-reason code — REQ-044): suppress the
 * "same nurse, different time" recovery when the nurse's reason reads like a hard gender/coverage block. */
const RETRY_BLOCK_KEYWORDS = ['gender', 'coverage', 'area', 'جنسیت', 'پوشش', 'منطقه', 'محدوده'];
function rejectionAllowsSameNurseRetry(reason: string | null): boolean {
  if (!reason) return true;
  const lower = reason.toLowerCase();
  return !RETRY_BLOCK_KEYWORDS.some((keyword) => lower.includes(keyword));
}

/**
 * C5 — Awaiting nurse acceptance (در انتظار تایید پرستار). Keyed by the request id, it **polls** the
 * request (`useBookingRequest`, stopping at a terminal status) so the accept / reject / expire transition
 * surfaces without a manual refresh. It renders the shared summary card, the 3-step tracker, and a
 * countdown driven by the **server-frozen** deadline: the response window while pending, then the 30-min
 * payment window once accepted (with the hand-off to checkout). Terminal states show their own card.
 */
export default function BookingRequestStatusPage() {
  const t = useTranslations('booking');
  const locale = useLocale();
  const router = useRouter();
  const params = useParams<{ id: string }>();
  const id = Number(params.id);

  const { data: request, isLoading, isError, refetch } = useBookingRequest(
    Number.isInteger(id) && id > 0 ? id : undefined,
    'customer',
  );
  const cancelRequest = useCancelBookingRequest();
  const [confirmCancel, setConfirmCancel] = useState(false);

  if (isLoading) return <StatusSkeleton />;

  if (isError || !request) {
    return (
      <TerminalCard
        icon="error"
        tone="var(--bal-error)"
        title={t('error_title')}
        primary={{ label: t('retry'), onClick: () => refetch() }}
      />
    );
  }

  const goToSearch = () => router.push(`/${locale}${ROUTES.SEARCH}`);

  /** Region + gender-carried search — "پرستاران مشابه": same city/district + the same caregiver-gender
   * intent, recovering the search context rather than restarting discovery from zero. */
  const goToSimilarNurses = () => {
    const searchParams = new URLSearchParams();
    searchParams.set('city_id', String(request.cityId));
    if (request.districtId != null) searchParams.set('district_id', String(request.districtId));
    if (request.requiredCaregiverGender === 'male' || request.requiredCaregiverGender === 'female') {
      searchParams.set('nurse_gender', request.requiredCaregiverGender);
    }
    router.push(`/${locale}${ROUTES.SEARCH}?${searchParams.toString()}`);
  };

  /** Reopens C4 for the SAME nurse/variant/patient/address, only the date/time left to re-pick — recovers
   * the booking intent instead of restarting from search. */
  const goToReRequestSameNurse = () => {
    const requestParams = new URLSearchParams();
    requestParams.set('nurse_id', String(request.nurseId));
    requestParams.set('variant_id', String(request.variantId));
    if (request.requiredCaregiverGender) requestParams.set('required_gender', request.requiredCaregiverGender);
    requestParams.set('patient_id', String(request.patientId));
    requestParams.set('address_id', String(request.customerAddressId));
    router.push(`/${locale}${ROUTES.BOOKING_REQUEST}?${requestParams.toString()}`);
  };

  const addressLabel = customerAddressLabel(request, locale, t('address_whole_city'));

  const summary = (
    <BookingRequestSummaryCard
      nurseName={request.nurseName}
      nurseRating={request.nurseRating}
      patientName={request.patientName}
      variantLabel={request.variantLabel}
      variantPrice={request.variantPrice}
      variantPriceUnit={request.variantPriceUnit}
      addressLabel={addressLabel}
      requestedDate={request.requestedDate}
      requestedTimeStart={request.requestedTimeStart}
      requestedTimeEnd={request.requestedTimeEnd}
    />
  );

  // Terminal states — each is its own card with a re-request path back into discovery (or booking).
  if (request.status === 'rejected_by_nurse') {
    const canRetrySameNurse = rejectionAllowsSameNurseRetry(request.nurseRejectionReason);
    return (
      <Stack sx={{ gap: 3 }}>
        {summary}
        <TerminalCard
          icon="rejected"
          tone="var(--bal-error)"
          title={t('rejected_title')}
          body={request.nurseRejectionReason ? `${t('rejected_reason_label')}: ${request.nurseRejectionReason}` : undefined}
          primary={
            canRetrySameNurse
              ? { label: t('terminal_rerequest_same_nurse'), onClick: goToReRequestSameNurse }
              : { label: t('terminal_similar_nurses'), onClick: goToSimilarNurses }
          }
          secondary={canRetrySameNurse ? { label: t('terminal_similar_nurses'), onClick: goToSimilarNurses } : undefined}
        />
      </Stack>
    );
  }
  if (request.status === 'expired_no_response') {
    return (
      <Stack sx={{ gap: 3 }}>
        {summary}
        <TerminalCard
          icon="pending"
          tone="var(--bal-warning)"
          title={t('expired_title')}
          primary={{ label: t('terminal_rerequest_same_nurse'), onClick: goToReRequestSameNurse }}
          secondary={{ label: t('terminal_similar_nurses'), onClick: goToSimilarNurses }}
        />
      </Stack>
    );
  }
  if (request.status === 'payment_deadline_expired') {
    return (
      <Stack sx={{ gap: 3 }}>
        {summary}
        <TerminalCard
          icon="pending"
          tone="var(--bal-warning)"
          title={t('payment_expired_title')}
          primary={{ label: t('terminal_rerequest'), onClick: goToSearch }}
        />
      </Stack>
    );
  }
  if (request.status === 'cancelled_by_customer') {
    return (
      <Stack sx={{ gap: 3 }}>
        {summary}
        <TerminalCard
          icon="rejected"
          tone="var(--bal-text-secondary)"
          title={t('cancelled_title')}
          primary={{ label: t('terminal_rerequest'), onClick: goToSearch }}
        />
      </Stack>
    );
  }
  if (request.status === 'converted') {
    return (
      <Stack sx={{ gap: 3 }}>
        {summary}
        <TerminalCard
          icon="verified"
          tone="var(--bal-success)"
          title={t('converted_title')}
          primary={{
            label: t('converted_cta'),
            // Deep-link the booking when the id is known (client-augmented, REQ-017); list fallback otherwise.
            onClick: () =>
              router.push(
                `/${locale}${request.bookingId != null ? `${ROUTES.BOOKINGS}/${request.bookingId}` : ROUTES.BOOKINGS}`,
              ),
          }}
        />
      </Stack>
    );
  }

  const accepted = request.status === 'accepted_awaiting_payment';
  const activeStep = accepted ? 2 : 1;

  return (
    <Stack sx={{ gap: 3 }}>
      <Stack sx={{ gap: 0.5, alignItems: 'center', textAlign: 'center' }}>
        <AppIcon icon="pending" size={40} color="var(--bal-primary)" />
        <Typography variant="h6" component="h1">
          {t('awaiting_title')}
        </Typography>
        <Typography variant="body2" sx={{ color: 'text.secondary' }}>
          {t('awaiting_subtitle')}
        </Typography>
      </Stack>

      <StepperHeader
        steps={[t('step_submitted'), t('step_awaiting'), t('step_payment')]}
        activeStep={activeStep}
      />

      {summary}

      {accepted ? (
        <Paper
          elevation={0}
          sx={{
            p: 2.5,
            borderRadius: 'var(--bal-radius-md)',
            border: '1px solid',
            borderColor: 'divider',
            borderInlineStartWidth: 4,
            borderInlineStartColor: 'var(--bal-secondary)',
          }}
        >
          <Stack sx={{ gap: 1.5, alignItems: 'center' }}>
            <StatusChip status="verified" label={t('accepted_badge')} />
            <Typography variant="body2" sx={{ color: 'text.secondary', textAlign: 'center' }}>
              {t('accepted_body')}
            </Typography>
            {request.paymentDeadlineAt ? (
              <CountdownTimer
                deadlineIso={request.paymentDeadlineAt}
                label={t('payment_countdown_label')}
                elapsedText={t('payment_elapsed')}
                urgent
                onElapsed={() => refetch()}
              />
            ) : null}
            <AppButton
              color="secondary"
              variant="contained"
              size="large"
              endIcon="forward"
              onClick={() => router.push(`/${locale}${ROUTES.CHECKOUT}?request_id=${request.id}`)}
              sx={{ py: 1.25 }}
            >
              {t('continue_payment')}
            </AppButton>
          </Stack>
        </Paper>
      ) : (
        <Paper elevation={0} sx={{ p: 2.5, borderRadius: 'var(--bal-radius-md)', border: '1px solid', borderColor: 'divider' }}>
          <Stack sx={{ gap: 1, alignItems: 'center' }}>
            <CountdownTimer
              deadlineIso={request.nurseResponseDeadlineAt}
              windowStart={request.createdAt}
              label={t('response_countdown_label')}
              elapsedText={t('response_elapsed')}
              coarseLabel={(minutes) => coarseResponseLabel(minutes, t)}
              onElapsed={() => refetch()}
            />
            <Typography variant="caption" sx={{ color: 'text.secondary' }}>
              {t('response_notify_note')}
            </Typography>
          </Stack>
        </Paper>
      )}

      <AppButton
        variant="text"
        color="error"
        disabled={cancelRequest.isPending}
        onClick={() => setConfirmCancel(true)}
        sx={{ alignSelf: 'center' }}
      >
        {cancelRequest.isPending ? t('cancelling') : t('cancel_request')}
      </AppButton>

      <ConfirmDialog
        open={confirmCancel}
        title={t('cancel_confirm_title')}
        body={t('cancel_confirm_body')}
        cancelLabel={t('cancel_confirm_keep')}
        confirmLabel={t('cancel_confirm_destructive')}
        confirmColor="error"
        loading={cancelRequest.isPending}
        onClose={() => setConfirmCancel(false)}
        onConfirm={() => {
          setConfirmCancel(false);
          cancelRequest.mutate(request.id);
        }}
      />
    </Stack>
  );
}

/** Humanized minutes-remaining copy above the coarse threshold («حدود ۳ ساعت» / «حدود ۲۵ دقیقه»). */
function coarseResponseLabel(minutes: number, t: (key: string, values?: Record<string, number>) => string): string {
  if (minutes >= MINUTES_PER_HOUR) {
    return t('countdown_about_hours', { hours: Math.round(minutes / MINUTES_PER_HOUR) });
  }
  return t('countdown_about_minutes', { minutes });
}

/** "title · city · district" (or "· whole city"), locale-aware — the customer view carries the full address. */
function customerAddressLabel(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 `${request.addressTitle} · ${city} · ${district}`;
}

interface TerminalAction {
  label: string;
  onClick: () => void;
}

function TerminalCard({
  icon,
  tone,
  title,
  body,
  primary,
  secondary,
}: {
  icon: string;
  tone: string;
  title: string;
  body?: string;
  primary: TerminalAction;
  secondary?: TerminalAction;
}) {
  return (
    <Paper elevation={0} sx={{ p: 4, textAlign: 'center', border: '1px solid', borderColor: 'divider', borderRadius: 'var(--bal-radius-md)' }}>
      <AppIcon icon={icon} size={44} color={tone} />
      <Typography variant="subtitle1" sx={{ fontWeight: 700, mt: 1, mb: body ? 0.5 : 2 }}>
        {title}
      </Typography>
      {body ? (
        <Typography variant="body2" sx={{ color: 'text.secondary', mb: 2 }}>
          {body}
        </Typography>
      ) : null}
      <Stack direction="row" sx={{ gap: 1, justifyContent: 'center', flexWrap: 'wrap' }}>
        <AppButton variant="contained" color="primary" onClick={primary.onClick}>
          {primary.label}
        </AppButton>
        {secondary ? (
          <AppButton variant="outlined" color="primary" onClick={secondary.onClick}>
            {secondary.label}
          </AppButton>
        ) : null}
      </Stack>
    </Paper>
  );
}

function StatusSkeleton() {
  return (
    <Stack sx={{ gap: 3 }}>
      <Stack sx={{ gap: 1, alignItems: 'center' }}>
        <Skeleton variant="circular" width={44} height={44} />
        <Skeleton variant="text" width="60%" height={28} />
      </Stack>
      <Skeleton variant="rounded" height={72} />
      <Skeleton variant="rounded" height={160} />
      <Skeleton variant="rounded" height={96} />
    </Stack>
  );
}
