'use client';
import { FunctionComponent } from 'react';
import { useLocale, useTranslations } from 'next-intl';
import { Chip, Paper, Skeleton, Stack, Typography } from '@mui/material';
import AccentCard from '@/components/common/AccentCard';
import AppIcon from '@/components/common/AppIcon';
import { formatShamsiDate } from '@/utils';
import { useBookingDetail, useCareInstructions } from '@/services/bookings';
import {
  isBookingConfirmedOrBeyond,
  type BookingDetailDto,
  type BookingViewerRole,
} from '@/services/bookings/types';
import BookingStatusTimeline from '../BookingStatusTimeline';
import SessionList from '../SessionList';
import BookingMoneySummary from '../BookingMoneySummary';
import CareInstructionsCard from '../CareInstructionsCard';
import { useEvvController } from '../useEvvController';

export interface BookingDetailViewProps {
  bookingId: number;
  /** `customer` sees the read-only timeline + sessions + money; `nurse` adds EVV controls + gated care. */
  viewerRole: BookingViewerRole;
}

/** Best-effort read of the frozen variant display name from the booking's variant snapshot. */
function variantName(snapshotJson: string): string | null {
  try {
    const parsed = JSON.parse(snapshotJson) as { displayName?: string };
    return parsed?.displayName ?? null;
  } catch {
    return null;
  }
}

/**
 * The both-roles booking detail — the hinge screen. Fetches `useBookingDetail`, renders the server-truth
 * `BookingStatusTimeline`, the `SessionList`, and the `BookingMoneySummary`. Role-conditioned: the
 * **assigned nurse** additionally gets the per-session EVV controls and the gated `CareInstructionsCard`;
 * the **customer** sees the read-only view and a "visible to your nurse only" affordance in place of the
 * clinical record.
 *
 * **Two-stage disclosure is a hard UI gate:** the care-instructions query is `enabled` **only** for the
 * nurse view on a `confirmed`+ booking — for the customer it never fires (a 404 would be a defect path,
 * not the design). Money is display-only; the timeline is never advanced client-side.
 * @component BookingDetailView
 */
const BookingDetailView: FunctionComponent<BookingDetailViewProps> = ({ bookingId, viewerRole }) => {
  const t = useTranslations('booking');
  const isNurse = viewerRole === 'nurse';

  const { data: booking, isLoading, isError } = useBookingDetail(bookingId, viewerRole);
  const careEnabled = isNurse && !!booking && isBookingConfirmedOrBeyond(booking.status);
  const care = useCareInstructions(bookingId, { enabled: careEnabled });
  const evv = useEvvController();

  if (isLoading) return <DetailSkeleton />;
  if (isError || !booking) return <NotFoundCard title={t('bd_not_found_title')} body={t('bd_not_found_body')} />;

  const service = variantName(booking.variantSnapshotJson);

  return (
    <Stack sx={{ gap: 3, maxWidth: 640, mx: 'auto', width: '100%' }} data-viewer-role={viewerRole}>
      {/* Header — carries the terracotta accent + "نمای پرستار" chip on the nurse view. */}
      <Paper
        elevation={0}
        sx={{
          p: 2.5,
          border: '1px solid',
          borderColor: 'divider',
          borderRadius: 2,
          ...(isNurse ? { borderTopWidth: 3, borderTopColor: 'var(--bal-secondary)' } : {}),
        }}
      >
        <Stack sx={{ gap: 1 }}>
          <Stack direction="row" sx={{ justifyContent: 'space-between', alignItems: 'flex-start', gap: 1.5, flexWrap: 'wrap' }}>
            <Typography variant="h6" component="h1">
              {service ?? t('bd_title')}
            </Typography>
            {isNurse ? (
              <Chip
                size="small"
                label={t('evv_nurse_view')}
                sx={{ bgcolor: 'var(--bal-secondary-soft)', color: 'var(--bal-secondary-dark)', fontWeight: 700 }}
              />
            ) : null}
          </Stack>
          <Typography variant="caption" sx={{ color: 'text.secondary' }}>
            {t('bd_ref', { id: booking.id })}
          </Typography>
          <Stack direction="row" sx={{ gap: 3, flexWrap: 'wrap', mt: 0.5 }}>
            <HeaderFact label={t('summary_patient')} value={booking.patientName} />
            <HeaderFact label={t('unnamed_nurse')} value={booking.nurseName} />
          </Stack>
        </Stack>
      </Paper>

      <Paper elevation={0} sx={{ p: 2.5, border: '1px solid', borderColor: 'divider', borderRadius: 2 }}>
        <BookingStatusTimeline status={booking.status} />
      </Paper>

      <StatusNote booking={booking} />

      <Stack sx={{ gap: 1.5 }}>
        <Typography variant="subtitle1" sx={{ fontWeight: 700 }}>
          {t('sessions_title')}
        </Typography>
        <SessionList
          sessions={booking.sessions}
          showEvvControls={isNurse}
          showPayout={isNurse}
          busySessionId={evv.busySessionId}
          acquiringSessionId={evv.acquiringSessionId}
          onCheckIn={isNurse ? (s) => evv.checkIn({ sessionId: s.id, bookingId: booking.id }) : undefined}
          onCheckOut={isNurse ? (s) => evv.checkOut({ sessionId: s.id, bookingId: booking.id }) : undefined}
        />
      </Stack>

      <BookingMoneySummary
        grossPriceIrr={booking.grossPriceIrr}
        balinyaarCommissionIrr={booking.balinyaarCommissionIrr}
        nursePayoutAmount={booking.nursePayoutAmount}
        viewerRole={viewerRole}
      />

      <CareSection viewerRole={viewerRole} careEnabled={careEnabled} care={care} />
    </Stack>
  );
};

function HeaderFact({ label, value }: { label: string; value: string }) {
  return (
    <Stack sx={{ gap: 0.25 }}>
      <Typography variant="caption" sx={{ color: 'text.secondary' }}>
        {label}
      </Typography>
      <Typography variant="body2" sx={{ fontWeight: 500 }}>
        {value}
      </Typography>
    </Stack>
  );
}

/** The per-status content note — confirmed/in-progress/completed(+dispute window)/disputed/cancelled. */
function StatusNote({ booking }: { booking: BookingDetailDto }) {
  const t = useTranslations('booking');
  const locale = useLocale();

  const lines: string[] = [];
  let tone: 'info' | 'warning' | 'neutral' = 'info';
  let icon = 'info';

  switch (booking.status) {
    case 'confirmed':
      lines.push(t('confirmed_note'));
      break;
    case 'in_progress':
      lines.push(t('in_progress_note'));
      break;
    case 'completed':
    case 'closed':
      lines.push(t('completed_note'));
      icon = 'verified';
      break;
    case 'disputed':
      lines.push(t('disputed_note'));
      tone = 'warning';
      icon = 'warning';
      break;
    case 'cancelled':
      lines.push(t('cancelled_note'));
      tone = 'neutral';
      icon = 'rejected';
      break;
    default:
      break;
  }

  if (booking.disputeWindowEndsAt && (booking.status === 'completed' || booking.status === 'closed')) {
    lines.push(t('dispute_window_note', { date: formatShamsiDate(booking.disputeWindowEndsAt, locale) }));
  }

  if (lines.length === 0) return null;

  const bg =
    tone === 'warning' ? 'var(--bal-secondary-soft)' : tone === 'neutral' ? 'var(--bal-divider)' : 'var(--bal-primary-soft)';
  const color = tone === 'warning' ? 'var(--bal-secondary-dark)' : 'var(--bal-text-secondary)';

  return (
    <Stack direction="row" sx={{ gap: 1, alignItems: 'flex-start', p: 1.5, borderRadius: 2, bgcolor: bg }}>
      <AppIcon icon={icon} size={18} color={color} />
      <Stack sx={{ gap: 0.25 }}>
        {lines.map((line) => (
          <Typography key={line} variant="body2" sx={{ color: 'text.secondary' }}>
            {line}
          </Typography>
        ))}
      </Stack>
    </Stack>
  );
}

/** The care-instructions region — the gated nurse card, or the customer's "visible to your nurse" note. */
function CareSection({
  viewerRole,
  careEnabled,
  care,
}: {
  viewerRole: BookingViewerRole;
  careEnabled: boolean;
  care: ReturnType<typeof useCareInstructions>;
}) {
  const t = useTranslations('booking');

  if (viewerRole !== 'nurse') {
    // Customer: never renders the clinical record and never fires the query.
    return (
      <AccentCard tone="neutral">
        <Stack direction="row" sx={{ gap: 1.25, alignItems: 'flex-start' }}>
          <AppIcon icon="lock" size={20} color="var(--bal-text-secondary)" />
          <Stack sx={{ gap: 0.25 }}>
            <Typography variant="subtitle2" sx={{ fontWeight: 700 }}>
              {t('care_locked_title')}
            </Typography>
            <Typography variant="body2" sx={{ color: 'text.secondary' }}>
              {t('care_locked_body')}
            </Typography>
          </Stack>
        </Stack>
      </AccentCard>
    );
  }

  if (!careEnabled) return null;
  if (care.isLoading) return <Skeleton variant="rounded" height={180} />;
  if (care.isError || !care.data) {
    return (
      <Paper elevation={0} sx={{ p: 2.5, border: '1px solid', borderColor: 'divider', borderRadius: 2 }}>
        <Typography variant="body2" sx={{ color: 'text.secondary' }}>
          {t('care_error')}
        </Typography>
      </Paper>
    );
  }
  return <CareInstructionsCard data={care.data} />;
}

function NotFoundCard({ title, body }: { title: string; body: string }) {
  return (
    <Paper
      elevation={0}
      sx={{ p: 4, textAlign: 'center', border: '1px solid', borderColor: 'divider', borderRadius: 2, maxWidth: 640, mx: 'auto' }}
    >
      <AppIcon icon="error" size={44} color="var(--bal-text-secondary)" />
      <Typography variant="subtitle1" sx={{ fontWeight: 700, mt: 1, mb: 0.5 }}>
        {title}
      </Typography>
      <Typography variant="body2" sx={{ color: 'text.secondary' }}>
        {body}
      </Typography>
    </Paper>
  );
}

function DetailSkeleton() {
  return (
    <Stack sx={{ gap: 3, maxWidth: 640, mx: 'auto', width: '100%' }}>
      <Skeleton variant="rounded" height={110} />
      <Skeleton variant="rounded" height={96} />
      <Skeleton variant="rounded" height={72} />
      <Skeleton variant="rounded" height={140} />
      <Skeleton variant="rounded" height={120} />
    </Stack>
  );
}

export default BookingDetailView;
