'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, Typography } from '@mui/material';
import { AppButton, AppIcon } from '@/components';
import { CascadingRegionSelect, type CascadingRegionValue } from '@/components/geography';
import { ApiError } from '@/lib/api/errors';
import { useServiceAreas, useAddServiceArea, useRemoveServiceArea } from '@/services/serviceAreas';
import { areaExists, type NurseServiceArea } from '@/services/serviceAreas/types';

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).
 *
 * ui-phase-8: **one control owns the whole-city choice** — `CascadingRegionSelect`'s own district
 * level, whose "کل شهر" empty option *is* the choice (`districtId = null`, matching the serviceAreas
 * contract both ways). The separate scope toggle this page used to render is gone — it let a nurse
 * pick "specific districts" and then still land on the district select's own whole-city option,
 * tripping a "district required" error the UI itself had offered. City is the only required field;
 * leaving the district unset is a complete, valid whole-city submission, never an error state.
 */
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 [cityError, setCityError] = useState(false);
  const [duplicate, setDuplicate] = useState(false);
  const [removeTarget, setRemoveTarget] = useState<NurseServiceArea | null>(null);

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

  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 resetForm = () => {
    setRegion(EMPTY_REGION);
    setCityError(false);
    setDuplicate(false);
  };

  const handleAdd = () => {
    const cityInvalid = region.cityId == null;
    setCityError(cityInvalid);
    setDuplicate(false);
    if (cityInvalid) return;

    const cityId = region.cityId as number;
    // Whatever the district select currently holds is the complete choice — `null` = whole city.
    const districtId = 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' }),
      onError: () => enqueueSnackbar(t('remove_error'), { variant: 'error' }),
    });
  };

  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: 'var(--bal-radius-md)',
            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: 'var(--bal-radius-md)' }}>
        <Stack sx={{ gap: 2 }}>
          <Typography variant="subtitle1" sx={{ fontWeight: 700 }}>
            {t('add_title')}
          </Typography>

          <CascadingRegionSelect
            value={region}
            onChange={(next) => {
              setRegion(next);
              if (cityError && next.cityId != null) setCityError(false);
              setDuplicate(false);
            }}
            cityError={cityError}
            cityErrorText={t('city_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>
  );
}
