'use client';
import { useState } from 'react';
import { useLocale, useTranslations } from 'next-intl';
import { useSnackbar } from 'notistack';
import {
  Box,
  Chip,
  Dialog,
  DialogActions,
  DialogContent,
  DialogTitle,
  Paper,
  Skeleton,
  Stack,
  ToggleButton,
  ToggleButtonGroup,
  Typography,
} from '@mui/material';
import { AppButton, AppIcon } from '@/components';
import { CascadingRegionSelect, type CascadingRegionValue } from '@/components/geography';
import { ApiError } from '@/lib/api/errors';
import { useDistricts } from '@/services/geography';
import { useServiceAreas, useAddServiceArea, useRemoveServiceArea } from '@/services/serviceAreas';
import { areaExists, type NurseServiceArea } from '@/services/serviceAreas/types';

type Scope = 'whole_city' | 'districts';
const EMPTY_REGION: CascadingRegionValue = { provinceId: null, cityId: null, districtId: null };

/**
 * The nurse coverage-area editor — the cities/districts a nurse will travel to, so search (f6)
 * can fan them out geographically. Areas render as chips (whole-city shown explicitly); the add
 * control is the cascading dropdowns + a whole-city vs specific-districts scope toggle. A
 * duplicate `(city, district)` is blocked inline before the request (and the server's 409 maps to
 * the same message). Empty → a warning that the nurse won't appear in search.
 */
export default function NurseCoveragePage() {
  const t = useTranslations('coverage');
  const tc = useTranslations('common');
  const locale = useLocale();
  const { enqueueSnackbar } = useSnackbar();

  const { data, isLoading } = useServiceAreas();
  const addArea = useAddServiceArea();
  const removeArea = useRemoveServiceArea();

  const [region, setRegion] = useState<CascadingRegionValue>(EMPTY_REGION);
  const [scope, setScope] = useState<Scope>('whole_city');
  const [cityError, setCityError] = useState(false);
  const [districtError, setDistrictError] = useState(false);
  const [duplicate, setDuplicate] = useState(false);
  const [removeTarget, setRemoveTarget] = useState<NurseServiceArea | null>(null);

  const areas = data?.items ?? [];

  // A whole-city-only city (no districts, e.g. Mashhad) can't satisfy "specific districts" — reads the
  // same cached districts query the cascade uses to force whole-city, so the toggle never dead-ends on a
  // district that cannot exist.
  const districtsQuery = useDistricts(region.cityId);
  const cityHasNoDistricts =
    region.cityId != null && districtsQuery.isSuccess && (districtsQuery.data?.length ?? 0) === 0;
  const effectiveScope: Scope = cityHasNoDistricts ? 'whole_city' : scope;

  const chipLabel = (area: NurseServiceArea) => {
    const city = locale === 'en' ? area.cityNameEn : area.cityNameFa;
    if (area.isWholeCity) return `${city} · ${t('whole_city_chip')}`;
    const district = locale === 'en' ? area.districtNameEn : area.districtNameFa;
    return `${city} · ${district}`;
  };

  const changeScope = (next: Scope | null) => {
    if (!next) return;
    setScope(next);
    setDistrictError(false);
    setDuplicate(false);
    // Whole-city ignores any picked district — clear it so the submitted pair is unambiguous.
    if (next === 'whole_city') setRegion((prev) => ({ ...prev, districtId: null }));
  };

  const resetForm = () => {
    setRegion(EMPTY_REGION);
    setScope('whole_city');
    setCityError(false);
    setDistrictError(false);
    setDuplicate(false);
  };

  const handleAdd = () => {
    const cityInvalid = region.cityId == null;
    const districtInvalid = effectiveScope === 'districts' && region.districtId == null;
    setCityError(cityInvalid);
    setDistrictError(districtInvalid);
    setDuplicate(false);
    if (cityInvalid || districtInvalid) return;

    const cityId = region.cityId as number;
    const districtId = effectiveScope === 'whole_city' ? null : region.districtId;

    // Fast path: block a duplicate before firing (null district treated as a real value).
    if (areaExists(areas, cityId, districtId)) {
      setDuplicate(true);
      return;
    }

    addArea.mutate(
      { cityId, districtId },
      {
        onSuccess: () => {
          resetForm();
          enqueueSnackbar(t('added'), { variant: 'success' });
        },
        onError: (error) => {
          // Belt-and-braces: the server's UNIQUE 409 maps to the same inline duplicate message.
          if (error instanceof ApiError && error.status === 409) setDuplicate(true);
          else enqueueSnackbar(t('add_error'), { variant: 'error' });
        },
      },
    );
  };

  const confirmRemove = () => {
    if (!removeTarget) return;
    const id = removeTarget.id;
    setRemoveTarget(null);
    removeArea.mutate(id, {
      onSuccess: () => enqueueSnackbar(t('removed'), { variant: 'success' }),
    });
  };

  return (
    <Box sx={{ display: 'flex', flexDirection: 'column', gap: 3, maxWidth: 560 }}>
      <Box>
        <Typography variant="h5" component="h1">
          {t('title')}
        </Typography>
        <Typography variant="body2" sx={{ color: 'text.secondary' }}>
          {t('subtitle')}
        </Typography>
      </Box>

      {isLoading ? (
        <Stack direction="row" sx={{ gap: 1, flexWrap: 'wrap' }}>
          {[0, 1].map((key) => (
            <Skeleton key={key} variant="rounded" width={160} height={32} />
          ))}
        </Stack>
      ) : areas.length > 0 ? (
        <Stack sx={{ gap: 1 }}>
          <Typography variant="subtitle2" sx={{ fontWeight: 700 }}>
            {t('areas_heading')}
          </Typography>
          <Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 1 }}>
            {areas.map((area) => (
              <Chip
                key={area.id}
                label={chipLabel(area)}
                onDelete={() => setRemoveTarget(area)}
                sx={{ bgcolor: 'var(--bal-primary-soft)', fontWeight: 500 }}
              />
            ))}
          </Box>
        </Stack>
      ) : (
        <Paper
          elevation={0}
          sx={{
            p: 2,
            borderRadius: 2,
            border: '1px solid',
            borderColor: 'divider',
            borderInlineStartWidth: 4,
            borderInlineStartColor: 'var(--bal-warning)',
          }}
        >
          <Stack direction="row" sx={{ gap: 1.5, alignItems: 'flex-start' }}>
            <AppIcon icon="warning" size={24} color="var(--bal-warning)" />
            <Box>
              <Typography variant="subtitle1" sx={{ fontWeight: 700 }}>
                {t('empty_title')}
              </Typography>
              <Typography variant="body2" sx={{ color: 'text.secondary' }}>
                {t('empty_warning')}
              </Typography>
            </Box>
          </Stack>
        </Paper>
      )}

      <Paper elevation={0} sx={{ p: 2.5, border: '1px solid', borderColor: 'divider', borderRadius: 2 }}>
        <Stack sx={{ gap: 2 }}>
          <Typography variant="subtitle1" sx={{ fontWeight: 700 }}>
            {t('add_title')}
          </Typography>

          <Stack sx={{ gap: 1 }}>
            <Typography variant="body2" sx={{ color: 'text.secondary' }}>
              {t('scope_label')}
            </Typography>
            <ToggleButtonGroup
              exclusive
              size="small"
              color="primary"
              value={effectiveScope}
              onChange={(_event, next: Scope | null) => changeScope(next)}
            >
              <ToggleButton value="whole_city">{t('scope_whole_city')}</ToggleButton>
              {/* A district-less city forces whole-city — disable the option rather than dead-end on it. */}
              <ToggleButton value="districts" disabled={cityHasNoDistricts}>
                {t('scope_districts')}
              </ToggleButton>
            </ToggleButtonGroup>
          </Stack>

          <CascadingRegionSelect
            value={region}
            onChange={(next) => {
              setRegion(next);
              if (cityError && next.cityId != null) setCityError(false);
              if (districtError && next.districtId != null) setDistrictError(false);
              setDuplicate(false);
            }}
            includeDistrict={effectiveScope === 'districts'}
            cityError={cityError}
            cityErrorText={t('city_required')}
            districtError={districtError}
            districtErrorText={t('district_required')}
          />

          {duplicate ? (
            <Typography variant="caption" sx={{ color: 'var(--bal-error)' }}>
              {t('duplicate')}
            </Typography>
          ) : null}

          <AppButton
            color="primary"
            variant="contained"
            startIcon="add"
            onClick={handleAdd}
            disabled={addArea.isPending}
            sx={{ alignSelf: 'flex-start' }}
          >
            {addArea.isPending ? t('adding') : t('add')}
          </AppButton>
        </Stack>
      </Paper>

      <Dialog open={Boolean(removeTarget)} onClose={() => setRemoveTarget(null)}>
        <DialogTitle>{t('remove_title')}</DialogTitle>
        <DialogContent>
          <Typography variant="body2" sx={{ color: 'text.secondary' }}>
            {t('remove_body')}
          </Typography>
        </DialogContent>
        <DialogActions>
          <AppButton variant="text" onClick={() => setRemoveTarget(null)}>
            {tc('cancel')}
          </AppButton>
          <AppButton color="error" variant="contained" onClick={confirmRemove}>
            {t('remove_confirm')}
          </AppButton>
        </DialogActions>
      </Dialog>
    </Box>
  );
}
