'use client';
import { useState } from 'react';
import { useTranslations } from 'next-intl';
import { useSnackbar } from 'notistack';
import { Box, Chip, MenuItem, Paper, Skeleton, Stack, TextField, Typography } from '@mui/material';
import { AppButton, RatingInput } from '@/components';
import { AdminEmptyState, AdminErrorState, AdminPageHeader, AdminPager, ConfirmDialog } from '@/components/admin';
import { useAdminCapabilities } from '@/hooks';
import { REVIEWS_PAGE_SIZE } from '@/services/reviews/constants';
import type { ModerationAction, ModerationQueueItem, ModerationStatus } from '@/services/reviews/types';
import { useModerationQueue, useModerateReview } from '@/services/reviews';

/** The moderation worklist tabs — the four `moderationStatus` values; the queue defaults to the pending backlog. */
const MODERATION_STATUSES: readonly ModerationStatus[] = ['pending_moderation', 'published', 'hidden', 'rejected'];

/** Status → MUI chip color. **Never** styles `pending_moderation` like a published review (it reads as a warning). */
const STATUS_CHIP_COLOR: Record<ModerationStatus, 'default' | 'success' | 'warning' | 'error'> = {
  pending_moderation: 'warning',
  published: 'success',
  hidden: 'default',
  rejected: 'error',
};

/**
 * Review moderation queue (f15) — the admin worklist over `reviews` awaiting a decision (b14). Each row carries
 * moderation internals (`lowRatingAlertId`, the nurse/booking context) that are **never** rendered on a
 * customer/nurse surface. A review is born `pending_moderation` and is never public / never counted until an
 * admin publishes it, so the card presents pending content as an under-review item, not as a published review.
 * Publishing recomputes the nurse aggregate **server-side**; the mutation invalidates the queue so the row
 * leaves on success. `canModerate` only hides the controls — the server enforces the role scope.
 */
export default function AdminReviewsPage() {
  const t = useTranslations('admin');
  const caps = useAdminCapabilities();
  const { enqueueSnackbar } = useSnackbar();

  const [status, setStatus] = useState<ModerationStatus>('pending_moderation');
  const [page, setPage] = useState(1);
  const [pending, setPending] = useState<{ item: ModerationQueueItem; action: ModerationAction } | null>(null);

  const queue = useModerationQueue({ status }, page);
  const moderate = useModerateReview();

  const items = queue.data?.items ?? [];
  const pageCount = Math.max(1, Math.ceil((queue.data?.total ?? 0) / REVIEWS_PAGE_SIZE));

  const requireReason = pending?.action === 'hide' || pending?.action === 'reject';

  const onConfirm = (reason?: string) => {
    if (!pending) return;
    moderate.mutate(
      { reviewId: pending.item.id, action: pending.action, reason },
      {
        onSuccess: () => {
          enqueueSnackbar(t('mod_done'), { variant: 'success' });
          setPending(null);
        },
      },
    );
  };

  return (
    <Box sx={{ display: 'flex', flexDirection: 'column', gap: 3 }}>
      <AdminPageHeader
        title={t('mod_title')}
        subtitle={t('mod_subtitle')}
        actions={
          <TextField
            select
            size="small"
            label={t('filter_label')}
            value={status}
            onChange={(e) => {
              setStatus(e.target.value as ModerationStatus);
              setPage(1);
            }}
            sx={{ minWidth: 180 }}
          >
            {MODERATION_STATUSES.map((s) => (
              <MenuItem key={s} value={s}>
                {t(`mstatus_${s}`)}
              </MenuItem>
            ))}
          </TextField>
        }
      />

      {queue.isLoading ? (
        <Stack sx={{ gap: 2 }}>{[0, 1, 2].map((k) => <Skeleton key={k} variant="rounded" height={150} />)}</Stack>
      ) : queue.isError ? (
        <AdminErrorState message={t('error_generic')} retryLabel={t('retry')} onRetry={() => queue.refetch()} />
      ) : items.length === 0 ? (
        <AdminEmptyState icon="moderation" title={t('mod_empty')} />
      ) : (
        <Stack sx={{ gap: 2 }}>
          {items.map((item) => (
            <ModerationCard
              key={item.id}
              item={item}
              canModerate={caps.canModerate}
              onAct={(action) => setPending({ item, action })}
            />
          ))}
        </Stack>
      )}

      <AdminPager
        page={page}
        pageCount={pageCount}
        onPrev={() => setPage((p) => Math.max(1, p - 1))}
        onNext={() => setPage((p) => Math.min(pageCount, p + 1))}
        prevLabel={t('prev_page')}
        nextLabel={t('next_page')}
        indicator={t('page_indicator', { page })}
      />

      <ConfirmDialog
        open={pending != null}
        title={pending ? t(`mod_${pending.action}`) : ''}
        body={pending ? t(`mod_confirm_${pending.action}`) : undefined}
        confirmLabel={pending ? t(`mod_${pending.action}`) : t('confirm')}
        cancelLabel={t('cancel')}
        confirmColor={pending?.action === 'reject' ? 'error' : 'primary'}
        loading={moderate.isPending}
        requireReason={requireReason}
        reasonLabel={t('reason_label')}
        onConfirm={onConfirm}
        onClose={() => setPending(null)}
      />
    </Box>
  );
}

/** One review awaiting a decision. Presentational; the actions bubble up to the page-level confirm dialog. */
function ModerationCard({
  item,
  canModerate,
  onAct,
}: {
  item: ModerationQueueItem;
  canModerate: boolean;
  onAct: (action: ModerationAction) => void;
}) {
  const t = useTranslations('admin');
  const tReviews = useTranslations('reviews');

  return (
    <Paper
      elevation={0}
      sx={{ p: 2.5, border: '1px solid', borderColor: 'divider', borderRadius: 2, display: 'flex', flexDirection: 'column', gap: 1.5 }}
    >
      <Stack direction="row" sx={{ gap: 1, alignItems: 'center', flexWrap: 'wrap' }}>
        <RatingInput value={item.rating} readOnly size={20} ariaLabel={t('mod_col_rating')} />
        <Chip size="small" color={STATUS_CHIP_COLOR[item.moderationStatus]} label={t(`mstatus_${item.moderationStatus}`)} />
        {item.lowRatingAlertId != null ? (
          <Chip size="small" color="warning" variant="outlined" label={t('mod_low_rating')} />
        ) : null}
      </Stack>

      {item.body ? (
        <Typography variant="body2" sx={{ color: 'text.primary' }}>
          {item.body}
        </Typography>
      ) : null}

      {item.tagCodes.length > 0 ? (
        <Stack direction="row" sx={{ gap: 0.5, flexWrap: 'wrap' }}>
          {item.tagCodes.map((code) => (
            <Chip key={code} size="small" variant="outlined" label={tReviews(`tag_${code}`)} />
          ))}
        </Stack>
      ) : null}

      <Stack direction="row" sx={{ gap: 2, flexWrap: 'wrap' }}>
        <Typography variant="caption" sx={{ color: 'text.secondary' }}>
          {t('mod_nurse', { id: item.nurseProfileId })}
        </Typography>
        <Typography variant="caption" sx={{ color: 'text.secondary' }}>
          {t('mod_booking', { id: item.bookingId })}
        </Typography>
      </Stack>

      {canModerate ? (
        <Stack direction="row" sx={{ gap: 1, flexWrap: 'wrap' }}>
          <AppButton variant="contained" color="primary" startIcon="publish" onClick={() => onAct('publish')}>
            {t('mod_publish')}
          </AppButton>
          <AppButton variant="outlined" color="inherit" onClick={() => onAct('hide')}>
            {t('mod_hide')}
          </AppButton>
          <AppButton variant="outlined" color="error" onClick={() => onAct('reject')}>
            {t('mod_reject')}
          </AppButton>
        </Stack>
      ) : null}
    </Paper>
  );
}
