'use client';
import { useState } from 'react';
import { useLocale, useTranslations } from 'next-intl';
import { useRouter } from 'next/navigation';
import { Badge, Skeleton, Stack, Tab, Tabs, Typography } from '@mui/material';
import { AccentCard, AppButton, CountdownTimer, EmptyState, ErrorState, Money, RatingInput, StatusChip } from '@/components';
import type { AccentTone, StatusKind } from '@/components';
import { BOOKING_STATUS_KIND } from '@/components/booking/statusKind';
import { bookingReviewPath, ROUTES } from '@/constants';
import { formatShamsiDate, localeTag } from '@/utils';
import { useBookingList } from '@/services/bookings';
import { BOOKINGS_PAGE_SIZE } from '@/services/bookings/constants';
import type { BookingListItemDto, BookingStatus } from '@/services/bookings/types';
import { useCustomerRequests } from '@/services/bookingRequests';
import type { BookingRequestListItem, BookingRequestStatus } from '@/services/bookingRequests/types';
import { useReviewEligibility } from '@/services/reviews';

type BookingsTab = 'pending' | 'active' | 'past';

/** `pending_payment`/`confirmed`/`in_progress` are still unfolding; the rest are resolved. */
const ACTIVE_BOOKING_STATUSES: readonly BookingStatus[] = ['pending_payment', 'confirmed', 'in_progress'];
const PAST_BOOKING_STATUSES: readonly BookingStatus[] = ['completed', 'disputed', 'closed', 'cancelled'];
const PENDING_REQUEST_STATUSES: readonly BookingRequestStatus[] = [
  'pending_nurse_response',
  'accepted_awaiting_payment',
];

const KIND_TO_ACCENT: Record<StatusKind, AccentTone> = {
  neutral: 'neutral',
  info: 'info',
  pending: 'primary',
  verified: 'success',
  active: 'success',
  rejected: 'error',
};

/**
 * Customer رزروها — the lifecycle home. Three tabs so a money-adjacent pending request is never orphaned
 * once the user leaves C5: **در انتظار پاسخ** wires the exported-but-previously-unused
 * `useCustomerRequests` (live mini-countdown per row, deep-linking back to C5); **فعال** / **گذشته** split
 * `useBookingList('customer')` by status. Rows carry a soft status chip + a matching `borderInlineStart`
 * accent and are fully tappable (keyboard-focusable). Pagination is a "load more" over a single growing
 * `pageSize` (the C2 results pattern) — booking #21+ stays reachable.
 */
export default function BookingsScreen() {
  const t = useTranslations('booking');
  const router = useRouter();
  const locale = useLocale();

  const [tab, setTab] = useState<BookingsTab>('active');
  const [pageSize, setPageSize] = useState(BOOKINGS_PAGE_SIZE);

  const pendingQuery = useCustomerRequests();
  const pendingItems = (pendingQuery.data?.items ?? []).filter((item) =>
    PENDING_REQUEST_STATUSES.includes(item.status),
  );

  const bookingsQuery = useBookingList('customer', { page: 1, pageSize });
  const allBookings = bookingsQuery.data?.items ?? [];
  const total = bookingsQuery.data?.total ?? 0;
  const hasMore = allBookings.length < total;
  const activeItems = allBookings.filter((item) => ACTIVE_BOOKING_STATUSES.includes(item.status));
  const pastItems = allBookings.filter((item) => PAST_BOOKING_STATUSES.includes(item.status));

  const openBooking = (id: number) => router.push(`/${locale}${ROUTES.BOOKINGS}/${id}`);
  const openRequest = (id: number) => router.push(`/${locale}${ROUTES.BOOKING_REQUEST_STATUS}/${id}`);
  const goToSearch = () => router.push(`/${locale}${ROUTES.SEARCH}`);

  return (
    <Stack sx={{ gap: 3 }}>
      <Stack>
        <Typography variant="h5" component="h1">
          {t('list_title')}
        </Typography>
        <Typography variant="body2" sx={{ color: 'text.secondary' }}>
          {t('list_subtitle')}
        </Typography>
      </Stack>

      <Tabs value={tab} onChange={(_event, value: BookingsTab) => setTab(value)} variant="fullWidth">
        <Tab
          value="pending"
          data-tab="pending"
          label={
            pendingItems.length > 0 ? (
              <Badge badgeContent={pendingItems.length} color="secondary" sx={{ '& .MuiBadge-badge': { insetInlineEnd: -12 } }}>
                {t('tab_pending')}
              </Badge>
            ) : (
              t('tab_pending')
            )
          }
        />
        <Tab value="active" data-tab="active" label={t('tab_active')} />
        <Tab value="past" data-tab="past" label={t('tab_past')} />
      </Tabs>

      {tab === 'pending' ? (
        pendingQuery.isLoading ? (
          <ListSkeleton />
        ) : pendingQuery.isError ? (
          <ErrorState message={t('inbox_error')} retryLabel={t('retry')} onRetry={() => pendingQuery.refetch()} />
        ) : pendingItems.length === 0 ? (
          <EmptyState
            icon="pending"
            title={t('pending_empty_title')}
            body={t('pending_empty_body')}
            action={
              <AppButton variant="outlined" color="primary" startIcon="search" onClick={goToSearch}>
                {t('missing_nurse_cta')}
              </AppButton>
            }
          />
        ) : (
          <Stack sx={{ gap: 2 }}>
            {pendingItems.map((item) => (
              <PendingRequestRow key={item.id} item={item} locale={locale} onOpen={() => openRequest(item.id)} />
            ))}
          </Stack>
        )
      ) : null}

      {tab === 'active' ? (
        bookingsQuery.isLoading ? (
          <ListSkeleton />
        ) : bookingsQuery.isError ? (
          <ErrorState message={t('list_error')} retryLabel={t('retry')} onRetry={() => bookingsQuery.refetch()} />
        ) : activeItems.length === 0 ? (
          <EmptyState
            icon="bookings"
            title={t('active_empty_title')}
            body={t('active_empty_body')}
            action={
              <AppButton variant="outlined" color="primary" startIcon="search" onClick={goToSearch}>
                {t('missing_nurse_cta')}
              </AppButton>
            }
          />
        ) : (
          <BookingRows items={activeItems} locale={locale} onOpen={openBooking} hasMore={hasMore} onLoadMore={() => setPageSize((size) => size + BOOKINGS_PAGE_SIZE)} loadingMore={bookingsQuery.isFetching} loadMoreLabel={t('load_more')} />
        )
      ) : null}

      {tab === 'past' ? (
        bookingsQuery.isLoading ? (
          <ListSkeleton />
        ) : bookingsQuery.isError ? (
          <ErrorState message={t('list_error')} retryLabel={t('retry')} onRetry={() => bookingsQuery.refetch()} />
        ) : pastItems.length === 0 ? (
          <EmptyState icon="bookings" title={t('past_empty_title')} body={t('past_empty_body')} />
        ) : (
          <BookingRows items={pastItems} locale={locale} onOpen={openBooking} hasMore={hasMore} onLoadMore={() => setPageSize((size) => size + BOOKINGS_PAGE_SIZE)} loadingMore={bookingsQuery.isFetching} loadMoreLabel={t('load_more')} />
        )
      ) : null}
    </Stack>
  );
}

function BookingRows({
  items,
  locale,
  onOpen,
  hasMore,
  onLoadMore,
  loadingMore,
  loadMoreLabel,
}: {
  items: BookingListItemDto[];
  locale: string;
  onOpen: (id: number) => void;
  hasMore: boolean;
  onLoadMore: () => void;
  loadingMore: boolean;
  loadMoreLabel: string;
}) {
  return (
    <Stack sx={{ gap: 2 }}>
      {items.map((item) => (
        <BookingRow key={item.id} item={item} locale={locale} onOpen={() => onOpen(item.id)} />
      ))}
      {hasMore ? (
        <AppButton variant="outlined" color="primary" onClick={onLoadMore} disabled={loadingMore} sx={{ alignSelf: 'center' }}>
          {loadMoreLabel}
        </AppButton>
      ) : null}
    </Stack>
  );
}

function BookingRow({ item, locale, onOpen }: { item: BookingListItemDto; locale: string; onOpen: () => void }) {
  const t = useTranslations('booking');
  const kind = BOOKING_STATUS_KIND[item.status];
  const isCompleted = item.status === 'completed' || item.status === 'closed';

  return (
    <AccentCard
      tone={KIND_TO_ACCENT[kind]}
      role="button"
      tabIndex={0}
      onClick={onOpen}
      onKeyDown={(event) => {
        if (event.key === 'Enter' || event.key === ' ') {
          event.preventDefault();
          onOpen();
        }
      }}
      data-booking-row={item.id}
      sx={{ cursor: 'pointer', '&:focus-visible': { outline: '2px solid var(--bal-primary)', outlineOffset: 2 } }}
    >
      <Stack sx={{ gap: 1.5 }}>
        <Stack direction="row" sx={{ justifyContent: 'space-between', alignItems: 'flex-start', gap: 1.5, flexWrap: 'wrap' }}>
          <Stack sx={{ gap: 0.25, minWidth: 0 }}>
            <Typography variant="subtitle1" sx={{ fontWeight: 700 }}>
              {item.counterpartyName}
            </Typography>
            <Typography variant="body2" sx={{ color: 'text.secondary' }}>
              {formatShamsiDate(item.scheduledDate, locale)} · {t('session_count', { count: item.sessionCount })}
            </Typography>
          </Stack>
          <StatusChip status={kind} label={t(`bstatus_${item.status}`)} />
        </Stack>

        <Typography variant="body2" sx={{ fontWeight: 700 }}>
          {t('list_total')}: <Money amountIrr={item.amountIrr} size="sm" sx={{ fontWeight: 700 }} />
        </Typography>

        {isCompleted ? <CompletedReviewStrip bookingId={item.id} enabled={isCompleted} /> : null}
      </Stack>
    </AccentCard>
  );
}

/** A completed booking without a review gets a compact star-strip CTA deep-linking into the review page.
 * The eligibility read is gated to completed/closed rows only (`enabled`) — an active booking never fires
 * it, and `canReview: false` (already reviewed or otherwise ineligible) renders nothing extra. */
function CompletedReviewStrip({ bookingId, enabled }: { bookingId: number; enabled: boolean }) {
  const t = useTranslations('reviews');
  const router = useRouter();
  const locale = useLocale();
  const eligibility = useReviewEligibility(bookingId, { enabled });

  if (!eligibility.data?.canReview) return null;

  return (
    <AppButton
      variant="text"
      color="primary"
      size="small"
      startIcon={<RatingInput value={0} readOnly size={16} ariaLabel={t('cta_leave')} />}
      onClick={(event) => {
        event.stopPropagation();
        router.push(`/${locale}${bookingReviewPath(bookingId)}`);
      }}
      sx={{ alignSelf: 'flex-start', px: 0 }}
    >
      {t('cta_leave')}
    </AppButton>
  );
}

/** «در انتظار پاسخ» row — a pending or accepted-awaiting-payment request, with a live mini-countdown. */
function PendingRequestRow({
  item,
  locale,
  onOpen,
}: {
  item: BookingRequestListItem;
  locale: string;
  onOpen: () => void;
}) {
  const t = useTranslations('booking');
  const accepted = item.status === 'accepted_awaiting_payment';
  const deadline = accepted ? item.paymentDeadlineAt : item.nurseResponseDeadlineAt;
  const timeFmt = new Intl.DateTimeFormat(localeTag(locale), { hour: '2-digit', minute: '2-digit' });
  const startDate = new Date(`${item.requestedDate}T${item.requestedTimeStart}`);
  const dateLabel = formatShamsiDate(startDate, locale);
  const timeLabel = timeFmt.format(startDate);

  return (
    <AccentCard
      tone={accepted ? 'secondary' : 'primary'}
      role="button"
      tabIndex={0}
      onClick={onOpen}
      onKeyDown={(event) => {
        if (event.key === 'Enter' || event.key === ' ') {
          event.preventDefault();
          onOpen();
        }
      }}
      data-request-row={item.id}
      sx={{ cursor: 'pointer', '&:focus-visible': { outline: '2px solid var(--bal-primary)', outlineOffset: 2 } }}
    >
      <Stack direction="row" sx={{ justifyContent: 'space-between', alignItems: 'center', gap: 1.5, flexWrap: 'wrap' }}>
        <Stack sx={{ gap: 0.25, minWidth: 0 }}>
          <Typography variant="subtitle1" sx={{ fontWeight: 700 }}>
            {item.counterpartyName}
          </Typography>
          <Typography variant="body2" sx={{ color: 'text.secondary' }}>
            {dateLabel} ·{' '}
            <Typography component="span" dir="ltr" sx={{ fontVariantNumeric: 'tabular-nums' }}>
              {timeLabel}
            </Typography>
          </Typography>
          <StatusChip status={accepted ? 'active' : 'pending'} label={t(`status_${item.status}`)} />
        </Stack>
        {deadline ? (
          <CountdownTimer
            deadlineIso={deadline}
            elapsedText={t(accepted ? 'payment_elapsed' : 'response_elapsed')}
            urgent={accepted}
            size="sm"
          />
        ) : null}
      </Stack>
    </AccentCard>
  );
}

function ListSkeleton() {
  return (
    <Stack sx={{ gap: 2 }}>
      {[0, 1].map((key) => (
        <Skeleton key={key} variant="rounded" height={96} />
      ))}
    </Stack>
  );
}
