'use client';
import { FunctionComponent, useEffect, useState } from 'react';
import { useRouter } from 'next/navigation';
import { useLocale, useTranslations } from 'next-intl';
import { Avatar, Box, ButtonBase, Paper, Skeleton, Stack, Typography } from '@mui/material';
import {
  AppButton,
  AppIcon,
  AppIconButton,
  AppLoading,
  CategoryTile,
  EmptyState,
  ErrorState,
  SurfaceCard,
} from '@/components';
import { ROUTES } from '@/constants';
import { useMe } from '@/services/auth';
import { usePatients } from '@/services/patients';
import { useServiceCategories } from '@/services/catalog';
import { pickCatalogName } from '@/services/catalog/names';
import { useBookingDetail, useBookingList } from '@/services/bookings';
import type { BookingListItemDto } from '@/services/bookings/types';

interface NudgeCardProps {
  icon: string;
  title: string;
  body: string;
  ctaLabel: string;
  to: string;
  /** Optional dismiss affordance (session-scoped) — omit for the always-relevant profile nudge. */
  onDismiss?: () => void;
  dismissLabel?: string;
}

const NudgeCard: FunctionComponent<NudgeCardProps> = ({ icon, title, body, ctaLabel, to, onDismiss, dismissLabel }) => (
  <Paper
    elevation={0}
    sx={{ p: 2.5, border: '1px solid', borderColor: 'divider', borderRadius: 'var(--bal-radius-md)', display: 'flex', gap: 2, position: 'relative' }}
  >
    <AppIcon icon={icon} size={28} color="var(--bal-primary)" />
    <Stack sx={{ gap: 1, flexGrow: 1, minWidth: 0 }}>
      <Stack sx={{ gap: 0.25 }}>
        <Typography variant="subtitle1" sx={{ fontWeight: 700, pr: onDismiss ? 4 : 0 }}>
          {title}
        </Typography>
        <Typography variant="body2" sx={{ color: 'text.secondary' }}>
          {body}
        </Typography>
      </Stack>
      <AppButton color="primary" variant="outlined" to={to} sx={{ alignSelf: 'flex-start' }}>
        {ctaLabel}
      </AppButton>
    </Stack>
    {onDismiss ? (
      <AppIconButton
        icon="close"
        title={dismissLabel}
        onClick={onDismiss}
        size="small"
        sx={{ position: 'absolute', insetInlineEnd: 8, insetBlockStart: 8 }}
      />
    ) : null}
  </Paper>
);

// Session-scoped dismiss: a plain module variable (not a cookie/localStorage — this is ephemeral UI
// state, not app/auth state) survives client-side navigation within the same page load and resets on a
// hard reload, matching "dismissible for this session, not permanently".
let patientNudgeDismissedInSession = false;

/**
 * A5 — the family Home: the front door of the app. Greeting + avatar, a compact ambient trust strip, a
 * tappable search entry point (routes to C1 — see `HomeSearchBar`), the **data-driven** service-category
 * grid (from the cached `services/catalog` reference data), a completeness-gated patient-record nudge,
 * and a "رزرو دوباره" (rebook) shortcut row sourced from recent bookings.
 *
 * First-login gate: a customer with no patients is sent into onboarding (A3). The redirect waits for
 * a settled list so a post-create refetch never bounces the user back to onboarding.
 */
export default function HomeScreen() {
  const t = useTranslations('home');
  const tc = useTranslations('common');
  const router = useRouter();
  const locale = useLocale();

  const { data: me } = useMe();
  const { data, isError, refetch } = usePatients();
  const [nudgeDismissed, setNudgeDismissed] = useState(patientNudgeDismissedInSession);

  const isEmpty = data?.total === 0;

  useEffect(() => {
    if (isEmpty) router.replace(`/${locale}${ROUTES.ONBOARDING}`);
  }, [isEmpty, router, locale]);

  if (isError) {
    return <ErrorState message={t('patients_error')} retryLabel={tc('retry')} onRetry={() => refetch()} />;
  }

  if (data == null || isEmpty) {
    return <AppLoading />;
  }

  const href = (path: string) => `/${locale}${path}`;
  const profileComplete = me?.hasCustomerProfile ?? false;
  const firstName = me?.firstName?.trim() || null;
  const greeting = firstName ? t('greeting_named', { name: firstName }) : t('greeting_plain');
  const avatarInitial = firstName ? firstName.charAt(0).toUpperCase() : null;

  // Completeness signal derived from the cached patients data (no extra fetch): a patient with no
  // conditions recorded yet is an incomplete record — never a forever-nudge once every record is filled.
  const hasIncompletePatient = data.items.some((patient) => patient.conditions.length === 0);
  const showPatientNudge = hasIncompletePatient && !nudgeDismissed;

  const dismissPatientNudge = () => {
    patientNudgeDismissedInSession = true;
    setNudgeDismissed(true);
  };

  return (
    <Box sx={{ display: 'flex', flexDirection: 'column', gap: 3 }}>
      <Stack direction="row" sx={{ gap: 1.5, alignItems: 'center' }}>
        <Avatar sx={{ width: 48, height: 48, bgcolor: 'var(--bal-primary-soft)', color: 'var(--bal-primary)', fontWeight: 700 }}>
          {avatarInitial ?? <AppIcon icon="account" size={28} color="var(--bal-primary)" />}
        </Avatar>
        <Box>
          <Typography variant="h5" component="h1">
            {greeting}
          </Typography>
          <Typography variant="body2" sx={{ color: 'text.secondary' }}>
            {t('subtitle')}
          </Typography>
        </Box>
      </Stack>

      <TrustStrip />

      <HomeSearchBar />

      <CategoryGrid onSelect={(categoryId) => router.push(`${href(ROUTES.SEARCH)}?category_id=${categoryId}`)} />

      <RebookRow />

      {showPatientNudge ? (
        <NudgeCard
          icon="patients"
          title={t('nudge_patient_title')}
          body={t('nudge_patient_body')}
          ctaLabel={t('nudge_patient_cta')}
          to={href(ROUTES.PATIENTS)}
          onDismiss={dismissPatientNudge}
          dismissLabel={tc('close')}
        />
      ) : null}
      {!profileComplete ? (
        <NudgeCard
          icon="profile"
          title={t('nudge_profile_title')}
          body={t('nudge_profile_body')}
          ctaLabel={t('nudge_profile_cta')}
          to={href(ROUTES.PROFILE)}
        />
      ) : null}
    </Box>
  );
}

/**
 * Quiet, one-line ambient reassurance under the greeting — not a hero. Three icon+label items: escrow
 * payment, verified nurses, support. Purely presentational; tokens only.
 */
const TrustStrip: FunctionComponent = () => {
  const t = useTranslations('home');
  const items: Array<{ icon: string; label: string }> = [
    { icon: 'lock', label: t('trust_escrow') },
    { icon: 'verification', label: t('trust_verified_nurses') },
    { icon: 'support', label: t('trust_support') },
  ];
  return (
    <Stack direction="row" sx={{ gap: 1, justifyContent: 'space-between' }}>
      {items.map((item) => (
        <Stack key={item.icon} direction="row" sx={{ gap: 0.5, alignItems: 'center', minWidth: 0 }}>
          <AppIcon icon={item.icon} size={16} color="var(--bal-primary)" />
          <Typography variant="caption" noWrap sx={{ color: 'text.secondary' }}>
            {item.label}
          </Typography>
        </Stack>
      ))}
    </Stack>
  );
};

/**
 * The Home search entry point — a tappable faux-input (never a half-working free-text field: the search
 * index has no text column, variant names aren't client-queryable, and the only matchable dataset — 5–6
 * cached category names — is already better served by the category grid directly below). Routes straight
 * to C1 (`/search`). **Upgrade path**: once the backend serves a `q` param on `search/nurses` (REQ-041,
 * matching nurse/variant/category names), this can become a real typeahead — the placeholder copy is
 * already written for that future, so only the tap target need change, not the copy/i18n keys.
 */
const HomeSearchBar: FunctionComponent = () => {
  const t = useTranslations('home');
  const router = useRouter();
  const locale = useLocale();

  return (
    <ButtonBase
      onClick={() => router.push(`/${locale}${ROUTES.SEARCH}`)}
      aria-label={t('search_action')}
      sx={{
        justifyContent: 'flex-start',
        gap: 1,
        width: '100%',
        px: 2,
        py: 1.5,
        borderRadius: 'var(--bal-radius-md)',
        border: '1px solid',
        borderColor: 'divider',
        bgcolor: 'background.paper',
        color: 'text.secondary',
      }}
    >
      <AppIcon icon="search" size={22} color="var(--bal-text-secondary)" />
      <Typography variant="body1">{t('search_placeholder')}</Typography>
    </ButtonBase>
  );
};

/** The data-driven service-category grid — one tile per `service_category`, with all four states. */
const CategoryGrid: FunctionComponent<{ onSelect: (categoryId: number) => void }> = ({ onSelect }) => {
  const t = useTranslations('home');
  const tc = useTranslations('common');
  const locale = useLocale();
  const { data, isLoading, isError, refetch } = useServiceCategories();
  const categories = data?.items ?? [];

  return (
    <Stack sx={{ gap: 1.5 }}>
      <Typography variant="subtitle1" sx={{ fontWeight: 700 }}>
        {t('categories_title')}
      </Typography>

      {isLoading ? (
        <Box sx={{ display: 'grid', gridTemplateColumns: { xs: 'repeat(2, 1fr)', sm: 'repeat(3, 1fr)' }, gap: 1.5 }}>
          {[0, 1, 2, 3].map((key) => (
            <Skeleton key={key} variant="rounded" height={116} sx={{ borderRadius: 'var(--bal-radius-md)' }} />
          ))}
        </Box>
      ) : isError ? (
        <ErrorState message={t('categories_error')} retryLabel={tc('retry')} onRetry={() => refetch()} />
      ) : categories.length === 0 ? (
        <EmptyState title={t('categories_empty')} />
      ) : (
        <Box sx={{ display: 'grid', gridTemplateColumns: { xs: 'repeat(2, 1fr)', sm: 'repeat(3, 1fr)' }, gap: 1.5 }}>
          {categories.map((category) => (
            <CategoryTile
              key={category.id}
              label={pickCatalogName(category, locale)}
              iconKey={category.iconKey}
              onClick={() => onSelect(category.id)}
            />
          ))}
        </Box>
      )}
    </Stack>
  );
};

/**
 * The "رزرو دوباره" shortcut row — repeat care is the dominant pattern in home nursing. Sourced from the
 * existing `useBookingList('customer')` cache (no extra list fetch); renders up to 2 cards, deduplicated
 * by nurse, deep-linking to the nurse's C3 profile. Renders nothing (no empty state) when there is no
 * past-bookings history.
 */
const RebookRow: FunctionComponent = () => {
  const { data, isLoading, isError } = useBookingList('customer', { pageSize: 5 });
  const items = data?.items ?? [];

  if (isLoading || isError || items.length === 0) return null;

  const seen = new Set<string>();
  const candidates: BookingListItemDto[] = [];
  for (const item of items) {
    if (seen.has(item.counterpartyName)) continue;
    seen.add(item.counterpartyName);
    candidates.push(item);
    if (candidates.length === 2) break;
  }

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

  return (
    <Stack sx={{ gap: 1 }}>
      {candidates.map((booking) => (
        <RebookCard key={booking.id} booking={booking} />
      ))}
    </Stack>
  );
};

/** One rebook card — resolves the booking's `nurseId` (not on the list row) via the cached booking
 * detail, then deep-links to the nurse's C3 profile. Renders nothing while resolving. */
const RebookCard: FunctionComponent<{ booking: BookingListItemDto }> = ({ booking }) => {
  const t = useTranslations('home');
  const router = useRouter();
  const locale = useLocale();
  const { data: detail } = useBookingDetail(booking.id, 'customer');

  if (!detail) return null;

  const open = () => router.push(`/${locale}${ROUTES.SEARCH_NURSE}/${detail.nurseId}`);

  return (
    <SurfaceCard
      padding="sm"
      onClick={open}
      role="button"
      tabIndex={0}
      onKeyDown={(event) => {
        if (event.key === 'Enter' || event.key === ' ') {
          event.preventDefault();
          open();
        }
      }}
      sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 2, cursor: 'pointer' }}
    >
      <Stack direction="row" sx={{ gap: 1, alignItems: 'center', minWidth: 0 }}>
        <AppIcon icon="history" size={20} color="var(--bal-primary)" />
        <Typography variant="body2" sx={{ fontWeight: 500 }} noWrap>
          {t('rebook_with', { name: booking.counterpartyName })}
        </Typography>
      </Stack>
      <AppIcon icon="forward" size={18} color="var(--bal-text-secondary)" />
    </SurfaceCard>
  );
};
