import React, { useState, useEffect } from 'react';
import { Box, Text, useInput } from 'ink';
import { useNavigation } from '../../state/navigation-context.js';
import { useRecipes } from '../../hooks/useRecipes.js';
import { useArticles } from '../../hooks/useArticles.js';
import { FormInput } from '../shared/FormInput.js';
import { ArticlePicker } from '../shared/ArticlePicker.js';
import { LoadingSpinner } from '../shared/LoadingSpinner.js';
import { ErrorDisplay } from '../shared/ErrorDisplay.js';
import { RECIPE_TYPE_LABELS, UOM_VALUES, UOM_LABELS } from '@effigenix/api-client';
import type { RecipeType, UoM, ArticleDTO } from '@effigenix/api-client';

type Field = 'name' | 'version' | 'type' | 'description' | 'yieldPercentage' | 'shelfLifeDays' | 'outputQuantity' | 'outputUom' | 'articleId';
const FIELDS: Field[] = ['name', 'version', 'type', 'description', 'yieldPercentage', 'shelfLifeDays', 'outputQuantity', 'outputUom', 'articleId'];

const FIELD_LABELS: Record<Field, string> = {
  name: 'Name *',
  version: 'Version *',
  type: 'Rezepttyp * (←→ wechseln)',
  description: 'Beschreibung',
  yieldPercentage: 'Ausbeute (%) *',
  shelfLifeDays: 'Haltbarkeit (Tage)',
  outputQuantity: 'Ausgabemenge *',
  outputUom: 'Mengeneinheit * (←→ wechseln)',
  articleId: 'Artikel *',
};

const RECIPE_TYPES: RecipeType[] = ['RAW_MATERIAL', 'INTERMEDIATE', 'FINISHED_PRODUCT'];

type TextFields = Exclude<Field, 'outputUom' | 'articleId'>;

export function RecipeCreateScreen() {
  const { replace, back } = useNavigation();
  const { createRecipe, loading, error, clearError } = useRecipes();
  const { articles, fetchArticles } = useArticles();

  const [values, setValues] = useState<Record<TextFields, string>>({
    name: '',
    version: '1',
    type: 'FINISHED_PRODUCT',
    description: '',
    yieldPercentage: '100',
    shelfLifeDays: '',
    outputQuantity: '',
  });
  const [uomIdx, setUomIdx] = useState(0);
  const [articleQuery, setArticleQuery] = useState('');
  const [selectedArticle, setSelectedArticle] = useState<{ id: string; name: string } | null>(null);
  const [activeField, setActiveField] = useState<Field>('name');
  const [fieldErrors, setFieldErrors] = useState<Partial<Record<Field, string>>>({});

  useEffect(() => { void fetchArticles(); }, []);

  const setField = (field: TextFields) => (value: string) => {
    setValues((v) => ({ ...v, [field]: value }));
  };

  const handleSubmit = async () => {
    const errors: Partial<Record<Field, string>> = {};
    if (!values.name.trim()) errors.name = 'Name ist erforderlich.';
    if (!values.version.trim() || isNaN(parseInt(values.version, 10))) errors.version = 'Version muss eine Zahl sein.';
    if (!values.type) errors.type = 'Rezepttyp ist erforderlich.';
    if (!values.yieldPercentage.trim() || isNaN(parseInt(values.yieldPercentage, 10))) errors.yieldPercentage = 'Ausbeute muss eine Zahl sein.';
    if (!values.outputQuantity.trim()) errors.outputQuantity = 'Ausgabemenge ist erforderlich.';
    if (!selectedArticle) errors.articleId = 'Artikel muss ausgewählt werden.';
    setFieldErrors(errors);
    if (Object.keys(errors).length > 0) return;

    const selectedUom = UOM_VALUES[uomIdx] as UoM;
    const result = await createRecipe({
      name: values.name.trim(),
      version: parseInt(values.version, 10),
      type: values.type as RecipeType,
      ...(values.description.trim() ? { description: values.description.trim() } : {}),
      yieldPercentage: parseInt(values.yieldPercentage, 10),
      ...(values.shelfLifeDays.trim() ? { shelfLifeDays: parseInt(values.shelfLifeDays, 10) } : {}),
      outputQuantity: values.outputQuantity.trim(),
      outputUom: selectedUom,
      articleId: selectedArticle!.id,
    });
    if (result) replace('recipe-list');
  };

  const handleFieldSubmit = (field: Field) => (_value: string) => {
    const idx = FIELDS.indexOf(field);
    if (idx < FIELDS.length - 1) {
      setActiveField(FIELDS[idx + 1] ?? field);
    } else {
      void handleSubmit();
    }
  };

  const handleArticleSelect = (article: ArticleDTO) => {
    setSelectedArticle({ id: article.id, name: `${article.name} (${article.articleNumber})` });
    setArticleQuery('');
  };

  useInput((_input, key) => {
    if (loading) return;
    if (activeField === 'articleId') {
      if (key.escape) back();
      if (key.tab || key.downArrow) setActiveField(FIELDS[0] ?? 'name');
      if (key.upArrow) setActiveField(FIELDS[FIELDS.length - 2] ?? 'outputUom');
      if (key.return && selectedArticle && !articleQuery) void handleSubmit();
      return;
    }

    if (activeField === 'type') {
      if (key.leftArrow || key.rightArrow) {
        const idx = RECIPE_TYPES.indexOf(values.type as RecipeType);
        const dir = key.rightArrow ? 1 : -1;
        const next = RECIPE_TYPES[(idx + dir + RECIPE_TYPES.length) % RECIPE_TYPES.length];
        if (next) setValues((v) => ({ ...v, type: next }));
        return;
      }
      if (key.return) {
        handleFieldSubmit('type')('');
        return;
      }
    }

    if (activeField === 'outputUom') {
      if (key.leftArrow || key.rightArrow) {
        const dir = key.rightArrow ? 1 : -1;
        setUomIdx((i) => (i + dir + UOM_VALUES.length) % UOM_VALUES.length);
        return;
      }
      if (key.return) {
        handleFieldSubmit('outputUom')('');
        return;
      }
    }

    if (key.tab || key.downArrow) {
      setActiveField((f) => {
        const idx = FIELDS.indexOf(f);
        return FIELDS[(idx + 1) % FIELDS.length] ?? f;
      });
    }
    if (key.upArrow) {
      setActiveField((f) => {
        const idx = FIELDS.indexOf(f);
        return FIELDS[(idx - 1 + FIELDS.length) % FIELDS.length] ?? f;
      });
    }
    if (key.escape) back();
  });

  if (loading) {
    return (
      <Box flexDirection="column" alignItems="center" paddingY={2}>
        <LoadingSpinner label="Rezept wird angelegt..." />
      </Box>
    );
  }

  const typeLabel = RECIPE_TYPE_LABELS[values.type as RecipeType] ?? values.type;
  const uomLabel = UOM_LABELS[UOM_VALUES[uomIdx] as UoM] ?? UOM_VALUES[uomIdx];

  return (
    <Box flexDirection="column" gap={1}>
      <Text color="cyan" bold>Neues Rezept</Text>
      {error && <ErrorDisplay message={error} onDismiss={clearError} />}

      <Box flexDirection="column" gap={1} width={60}>
        {FIELDS.map((field) => {
          if (field === 'type') {
            return (
              <Box key={field} flexDirection="column">
                <Text color={activeField === field ? 'cyan' : 'gray'}>
                  {FIELD_LABELS[field]}: <Text bold color="white">{activeField === field ? `< ${typeLabel} >` : typeLabel}</Text>
                </Text>
                {fieldErrors[field] && <Text color="red">{fieldErrors[field]}</Text>}
              </Box>
            );
          }
          if (field === 'outputUom') {
            return (
              <Box key={field} flexDirection="column">
                <Text color={activeField === field ? 'cyan' : 'gray'}>
                  {FIELD_LABELS[field]}: <Text bold color="white">{activeField === field ? `< ${uomLabel} >` : uomLabel}</Text>
                </Text>
              </Box>
            );
          }
          if (field === 'articleId') {
            return (
              <Box key={field} flexDirection="column">
                <ArticlePicker
                  articles={articles}
                  query={articleQuery}
                  onQueryChange={setArticleQuery}
                  onSelect={handleArticleSelect}
                  focus={activeField === 'articleId'}
                  {...(selectedArticle ? { selectedName: selectedArticle.name } : {})}
                />
                {fieldErrors[field] && <Text color="red">{fieldErrors[field]}</Text>}
              </Box>
            );
          }
          const tf = field as TextFields;
          return (
            <FormInput
              key={field}
              label={FIELD_LABELS[field]}
              value={values[tf]}
              onChange={setField(tf)}
              onSubmit={handleFieldSubmit(field)}
              focus={activeField === field}
              {...(fieldErrors[field] ? { error: fieldErrors[field] } : {})}
            />
          );
        })}
      </Box>

      <Box marginTop={1}>
        <Text color="gray" dimColor>
          Tab/↑↓ Feld wechseln · ←→ Rezepttyp/Einheit · Artikel: Suche tippen, Enter auswählen, nochmal Enter speichern · Escape Abbrechen
        </Text>
      </Box>
    </Box>
  );
}
