import { useEffect, useMemo, useState } from 'react';

import Box from '@mui/material/Box';
import Button from '@mui/material/Button';
import MenuItem from '@mui/material/MenuItem';
import Stack from '@mui/material/Stack';
import TextField from '@mui/material/TextField';
import Typography from '@mui/material/Typography';

import {
  adminApi,
  type AdminServiceCategory,
} from '../../../../api';
import { ApiError } from '../../../../api/httpClient.ts';
import { defaultServiceFormValues, type ServiceFormValues } from './service-form.helpers.ts';

const SERVICE_STATUSES = [
  { value: 'PUBLISHED', label: 'Опубликовано' },
  { value: 'DRAFT', label: 'Черновик' },
  { value: 'ARCHIVED', label: 'Архив' },
];

type FieldErrors = Partial<Record<keyof ServiceFormValues, string>>;

export interface ServiceFormProps {
  mode: 'create' | 'edit';
  initialValues?: ServiceFormValues;
  submitLabel: string;
  onSubmit: (values: ServiceFormValues) => Promise<void>;
  onCancel: () => void;
  isSubmitting: boolean;
}

export const ServiceForm: React.FC<ServiceFormProps> = ({
  mode,
  initialValues,
  submitLabel,
  onSubmit,
  onCancel,
  isSubmitting,
}) => {
  const [form, setForm] = useState<ServiceFormValues>(initialValues ?? defaultServiceFormValues);
  const [errors, setErrors] = useState<FieldErrors>({});
  const [categories, setCategories] = useState<AdminServiceCategory[]>([]);
  const [categoriesError, setCategoriesError] = useState<string | null>(null);
  const [isLoadingCategories, setIsLoadingCategories] = useState(false);

  const initialValuesKey = useMemo(() => JSON.stringify(initialValues ?? defaultServiceFormValues), [initialValues]);

  useEffect(() => {
    if (!initialValues) {
      setForm(defaultServiceFormValues);
      return;
    }
    setForm(initialValues);
  }, [initialValuesKey, initialValues]);

  useEffect(() => {
    const loadCategories = async () => {
      setIsLoadingCategories(true);
      setCategoriesError(null);
      try {
        const payload = await adminApi.listServiceCategories();
        setCategories(payload);
      } catch (err) {
        const message = err instanceof ApiError ? err.message : 'Не удалось загрузить категории услуг.';
        setCategoriesError(message);
      } finally {
        setIsLoadingCategories(false);
      }
    };

    void loadCategories();
  }, []);

  const validate = (): boolean => {
    const next: FieldErrors = {};
    if (!form.title.trim()) {
      next.title = 'Введите название услуги';
    }
    if (!form.slug.trim()) {
      next.slug = 'Введите slug услуги';
    }
    if (!form.description.trim()) {
      next.description = 'Введите описание услуги';
    }
    if (form.priceFrom && Number.isNaN(Number(form.priceFrom))) {
      next.priceFrom = 'Введите корректную стоимость';
    }
    if (form.imageUrl && !/^https?:\/\//i.test(form.imageUrl.trim())) {
      next.imageUrl = 'Укажите ссылку, начинающуюся с http:// или https://';
    }

    setErrors(next);
    return Object.keys(next).length === 0;
  };

  const handleChange = (event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
    const { name, value } = event.target;
    setForm((prev) => ({
      ...prev,
      [name]: value,
    }));
    if (errors[name as keyof ServiceFormValues]) {
      setErrors((prev) => ({
        ...prev,
        [name]: undefined,
      }));
    }
  };

  const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
    event.preventDefault();
    if (!validate()) {
      return;
    }
    await onSubmit(form);
  };

  const isCategorySelectDisabled = isLoadingCategories || categoriesError !== null || categories.length === 0;

  return (
    <Box component="form" onSubmit={handleSubmit} sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
      <TextField
        label="Название"
        name="title"
        value={form.title}
        onChange={handleChange}
        required
        error={Boolean(errors.title)}
        helperText={errors.title}
        fullWidth
      />
      <TextField
        label="Slug"
        name="slug"
        value={form.slug}
        onChange={handleChange}
        required
        error={Boolean(errors.slug)}
        helperText={errors.slug ?? 'Используется в URL услуги'}
        fullWidth
      />
      <TextField
        label="Описание"
        name="description"
        value={form.description}
        onChange={handleChange}
        required
        error={Boolean(errors.description)}
        helperText={errors.description}
        multiline
        minRows={4}
        fullWidth
      />
      <Stack direction={{ xs: 'column', md: 'row' }} spacing={2}>
        <TextField
          label="Стоимость от"
          name="priceFrom"
          type="number"
          value={form.priceFrom}
          onChange={handleChange}
          error={Boolean(errors.priceFrom)}
          helperText={errors.priceFrom ?? 'Число в рублях, например 1500'}
          inputProps={{ min: 0, step: '0.01' }}
          fullWidth
        />
        <TextField
          select
          label="Категория"
          name="categoryId"
          value={form.categoryId}
          onChange={handleChange}
          fullWidth
          disabled={isCategorySelectDisabled}
          helperText={
            categoriesError
              ? categoriesError
              : isLoadingCategories
                ? 'Загружаем категории...'
                : 'Выберите категорию или оставьте пустым'
          }
        >
          <MenuItem value="">Без категории</MenuItem>
          {categories.map((category) => (
            <MenuItem key={category.id} value={String(category.id)}>
              {category.name}
            </MenuItem>
          ))}
        </TextField>
      </Stack>
      <TextField
        label="Изображение (URL)"
        name="imageUrl"
        value={form.imageUrl}
        onChange={handleChange}
        error={Boolean(errors.imageUrl)}
        helperText={errors.imageUrl ?? 'Необязательно'}
        fullWidth
      />
      <TextField
        select
        label="Статус"
        name="status"
        value={form.status}
        onChange={handleChange}
        fullWidth
        helperText="Выберите статус публикации"
      >
        {SERVICE_STATUSES.map((status) => (
          <MenuItem key={status.value} value={status.value}>
            {status.label}
          </MenuItem>
        ))}
      </TextField>
      <Stack direction="row" spacing={2} justifyContent="flex-end" flexWrap="wrap">
        <Button variant="outlined" color="inherit" onClick={onCancel} disabled={isSubmitting}>
          Отмена
        </Button>
        <Button type="submit" variant="contained" disabled={isSubmitting}>
          {isSubmitting ? 'Сохраняем…' : submitLabel}
        </Button>
      </Stack>
      {mode === 'edit' && (
        <Typography variant="caption" color="text.secondary">
          Все изменения сохраняются после нажатия «{submitLabel}».
        </Typography>
      )}
    </Box>
  );
};
