'use client';
import { ReactNode } from 'react';
import { useLocale, useTranslations } from 'next-intl';
import { Box, Skeleton, Stack, Typography } from '@mui/material';
import {
  AccentCard,
  AppButton,
  AppLink,
  CountdownTimer,
  EmptyState,
  ErrorState,
  Money,
  PageHeader,
  SurfaceCard,
} from '@/components';
import { ROUTES } from '@/constants';
import { formatRelativeTime, formatShamsiDate, localeTag, parseIrr } from '@/utils';
import { useNurseRequestInbox } from '@/services/bookingRequests';
import { useTodaySessions } from '@/services/bookings';
import { useNurseEarningsBalance } from '@/services/payouts';
import { coarseResponseLabel } from '@/services/bookingRequests/format';
import DashboardActivationSlot from './DashboardActivationSlot';

/** The pill's urgency tiers (ui-phase-7 §3.4): teal >2h · amber <2h · terracotta <30min. */
const URGENT_THRESHOLD_SECONDS = 30 * 60;
const WARN_THRESHOLD_SECONDS = 2 * 60 * 60;

/**
 * The nurse «امروز» home — the first bottom-nav destination.
 *
 * Rebuilt for the phone-width frame. The previous version stacked five same-weight cards, each
 * repeating its own icon + bold heading + inline "see all" button; at 480px the buttons wrapped
 * mid-word, the countdown collided with the request title, and nothing on the screen looked more
 * important than anything else. This version gives the page one visual hierarchy: exactly one hero
 * action (the next visit), then sections introduced by a plain label with a text link instead of a
 * competing button.
 *
 * The greeting/identity strip that used to sit above all of it is gone: it spent the most valuable
 * row on the screen restating the signed-in name to the person who typed the phone number, and the
 * badge beside it duplicated the activation tracker further down. Identity now lives in the shell's
 * top bar (`NurseAccountButton`), where it costs no content height and opens the account hub.
 *
 * Composition only — every widget reads a query that is already cached elsewhere in the shell, and
 * order encodes urgency: a missed request expires, an unread earnings figure does not.
 */
export default function NurseDashboardScreen() {
  const t = useTranslations('dashboard');
  return (
    <Stack sx={{ gap: 2.5 }}>
      {/* Load-bearing now that the bottom nav is icon-only: this is the only place the current
          section is named, and the page's only h1. */}
      <PageHeader title={t('title')} />
      <NextVisitCard />
      <RequestsSection />
      <EarningsSection />
      <DashboardActivationSlot />
    </Stack>
  );
}

/**
 * A section label + an optional text link. Deliberately not a button: on a 480px row a
 * `<Button>` labelled «مشاهده همه» wrapped to two lines and outweighed the section it introduced.
 */
function SectionHeader({ title, actionLabel, actionTo }: { title: string; actionLabel?: string; actionTo?: string }) {
  const locale = useLocale();
  return (
    <Stack direction="row" sx={{ alignItems: 'baseline', justifyContent: 'space-between', gap: 1 }}>
      <Typography variant="subtitle2" sx={{ fontWeight: 700 }}>
        {title}
      </Typography>
      {actionLabel && actionTo ? (
        <AppLink to={`/${locale}${actionTo}`} variant="caption" color="primary" sx={{ flexShrink: 0 }}>
          {actionLabel}
        </AppLink>
      ) : null}
    </Stack>
  );
}

/** The page's one hero action: the next actionable session, with a full-width primary CTA. */
function NextVisitCard() {
  const t = useTranslations('dashboard');
  const locale = useLocale();
  const { data, isLoading, isError, refetch } = useTodaySessions();

  if (isLoading) return <Skeleton variant="rounded" height={150} sx={{ borderRadius: 'var(--bal-radius-md)' }} />;
  if (isError) {
    return <ErrorState message={t('next_visit_error')} retryLabel={t('retry')} onRetry={() => refetch()} />;
  }

  const next = (data?.items ?? []).find((item) => item.status === 'scheduled' || item.status === 'in_progress');

  if (!next) {
    return (
      <Stack sx={{ gap: 1 }}>
        <SectionHeader title={t('next_visit_title')} />
        <EmptyState icon="visits" title={t('next_visit_empty')} />
      </Stack>
    );
  }

  const timeFmt = new Intl.DateTimeFormat(localeTag(locale), { hour: '2-digit', minute: '2-digit' });
  const timeRangeLabel = `${timeFmt.format(new Date(`${next.scheduledDate}T${next.scheduledTimeStart}`))} – ${timeFmt.format(new Date(`${next.scheduledDate}T${next.scheduledTimeEnd}`))}`;
  const timeUntil = formatRelativeTime(`${next.scheduledDate}T${next.scheduledTimeStart}`, locale, formatShamsiDate);

  return (
    <AccentCard tone="secondary" data-widget="next-visit">
      <Stack sx={{ gap: 1.5 }}>
        <Stack sx={{ gap: 0.25, minWidth: 0 }}>
          <Typography variant="overline" sx={{ color: 'text.secondary' }}>
            {t('next_visit_title')}
          </Typography>
          <Typography variant="h6" sx={{ fontWeight: 700 }}>
            {next.patientName}
          </Typography>
          <MetaLine
            items={[
              <Box key="range" component="span" dir="ltr" sx={{ fontVariantNumeric: 'tabular-nums' }}>
                {timeRangeLabel}
              </Box>,
              timeUntil ? t('next_visit_starts_in', { relative: timeUntil }) : null,
            ]}
          />
        </Stack>

        <AppButton variant="contained" color="secondary" startIcon="check_in" fullWidth to={`/${locale}${ROUTES.NURSE_VISITS}`}>
          {t('next_visit_cta')}
        </AppButton>
      </Stack>
    </AccentCard>
  );
}

/** The most time-critical section: a pending request expires on its own if it isn't answered. */
function RequestsSection() {
  const t = useTranslations('dashboard');
  const tb = useTranslations('booking');
  const locale = useLocale();
  const { data, isLoading, isError, refetch } = useNurseRequestInbox();

  if (isLoading) return <Skeleton variant="rounded" height={130} sx={{ borderRadius: 'var(--bal-radius-md)' }} />;
  if (isError) {
    return <ErrorState message={t('requests_strip_error')} retryLabel={t('retry')} onRetry={() => refetch()} />;
  }

  const items = data?.items ?? [];
  const total = data?.total ?? 0;

  if (items.length === 0) {
    return (
      <Stack sx={{ gap: 1 }}>
        <SectionHeader title={t('requests_strip_title', { count: 0 })} />
        <EmptyState icon="requests" title={t('requests_strip_empty')} />
      </Stack>
    );
  }

  const mostUrgent = items[0];

  return (
    <Stack sx={{ gap: 1 }} data-widget="requests-strip">
      <SectionHeader
        title={t('requests_strip_title', { count: total })}
        actionLabel={t('requests_strip_cta')}
        actionTo={ROUTES.NURSE_REQUESTS}
      />

      <SurfaceCard>
        <Stack sx={{ gap: 1.5 }}>
          {/* Name and countdown are siblings on one row, with the pill `flexShrink: 0` — the old
              layout let the countdown wrap under a long Persian name and collide with the date. */}
          <Stack direction="row" sx={{ gap: 1, alignItems: 'center', justifyContent: 'space-between' }}>
            <Stack sx={{ gap: 0.25, minWidth: 0 }}>
              <Typography variant="body1" noWrap sx={{ fontWeight: 500 }}>
                {mostUrgent.counterpartyName}
              </Typography>
              <Typography variant="caption" sx={{ color: 'text.secondary' }}>
                {formatShamsiDate(mostUrgent.requestedDate, locale)}
              </Typography>
            </Stack>
            <Box sx={{ flexShrink: 0 }}>
              <CountdownTimer
                deadlineIso={mostUrgent.nurseResponseDeadlineAt}
                elapsedText={tb('response_elapsed')}
                warnThresholdSeconds={WARN_THRESHOLD_SECONDS}
                urgentThresholdSeconds={URGENT_THRESHOLD_SECONDS}
                coarseLabel={(minutes) => coarseResponseLabel(minutes, tb)}
                size="sm"
              />
            </Box>
          </Stack>

          <AppButton
            variant="outlined"
            color="primary"
            fullWidth
            to={`/${locale}${ROUTES.NURSE_REQUESTS}/${mostUrgent.id}`}
          >
            {t('requests_strip_open')}
          </AppButton>
        </Stack>
      </SurfaceCard>
    </Stack>
  );
}

/** Two stat tiles — the signed net balance is never clamped, an "owed back" reads as an error tone. */
function EarningsSection() {
  const t = useTranslations('dashboard');
  const tp = useTranslations('payouts');
  const { data, isLoading, isError, refetch } = useNurseEarningsBalance();

  if (isLoading) return <Skeleton variant="rounded" height={110} sx={{ borderRadius: 'var(--bal-radius-md)' }} />;
  if (isError) {
    return <ErrorState message={t('earnings_snapshot_error')} retryLabel={t('retry')} onRetry={() => refetch()} />;
  }
  if (!data) return null;

  const net = parseIrr(data.netPayableBalanceIrr);
  const isOwed = net < BigInt(0);
  const magnitude = isOwed ? -net : net;

  return (
    <Stack sx={{ gap: 1 }} data-widget="earnings-snapshot">
      <SectionHeader
        title={t('earnings_snapshot_title')}
        actionLabel={t('earnings_snapshot_cta')}
        actionTo={ROUTES.NURSE_EARNINGS}
      />

      <Box sx={{ display: 'grid', gap: 1.5, gridTemplateColumns: '1fr 1fr' }}>
        <StatTile
          label={isOwed ? tp('balance_owed_label') : tp('balance_net_label')}
          value={<Money amountIrr={String(magnitude)} size="lg" tone={isOwed ? 'error' : 'emphasis'} />}
        />
        <StatTile label={tp('bucket_eligible')} value={<Money amountIrr={data.eligibleTotalIrr} size="lg" />} />
      </Box>
    </Stack>
  );
}

function StatTile({ label, value }: { label: string; value: ReactNode }) {
  return (
    <SurfaceCard padding="sm">
      <Stack sx={{ gap: 0.25, minWidth: 0 }}>
        <Typography variant="caption" noWrap sx={{ color: 'text.secondary' }}>
          {label}
        </Typography>
        {value}
      </Stack>
    </SurfaceCard>
  );
}

/** Dot-separated secondary facts on one line, skipping the ones that aren't available. */
function MetaLine({ items }: { items: Array<ReactNode> }) {
  const present = items.filter(Boolean);
  return (
    <Typography variant="body2" sx={{ color: 'text.secondary' }}>
      {present.map((item, index) => (
        <Box key={index} component="span">
          {index > 0 ? ' · ' : null}
          {item}
        </Box>
      ))}
    </Typography>
  );
}
