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

type Field = 'articleId' | 'storageLocationId' | 'minimumLevelAmount' | 'minimumLevelUnit' | 'minimumShelfLifeDays';
const FIELDS: Field[] = ['articleId', 'storageLocationId', 'minimumLevelAmount', 'minimumLevelUnit', 'minimumShelfLifeDays'];

const FIELD_LABELS: Record<Field, string> = {
  articleId: 'Artikel *',
  storageLocationId: 'Lagerort * (↑↓ auswählen)',
  minimumLevelAmount: 'Mindestbestand Menge',
  minimumLevelUnit: 'Mindestbestand Einheit (←→ wechseln)',
  minimumShelfLifeDays: 'Mindest-MHD (Tage)',
};

export function StockCreateScreen() {
  const { replace, back } = useNavigation();
  const { createStock, loading, error, clearError } = useStocks();
  const { articles, fetchArticles } = useArticles();
  const { storageLocations, fetchStorageLocations } = useStorageLocations();

  const [articleQuery, setArticleQuery] = useState('');
  const [selectedArticle, setSelectedArticle] = useState<{ id: string; name: string } | null>(null);
  const [locationIdx, setLocationIdx] = useState(0);
  const [minimumLevelAmount, setMinimumLevelAmount] = useState('');
  const [uomIdx, setUomIdx] = useState(0);
  const [minimumShelfLifeDays, setMinimumShelfLifeDays] = useState('');
  const [activeField, setActiveField] = useState<Field>('articleId');
  const [fieldErrors, setFieldErrors] = useState<Partial<Record<Field, string>>>({});

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

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

  const handleSubmit = async () => {
    const errors: Partial<Record<Field, string>> = {};
    if (!selectedArticle) errors.articleId = 'Artikel muss ausgewählt werden.';
    if (storageLocations.length === 0) errors.storageLocationId = 'Kein Lagerort verfügbar.';
    setFieldErrors(errors);
    if (Object.keys(errors).length > 0) return;

    const location = storageLocations[locationIdx] as StorageLocationDTO;
    const result = await createStock({
      articleId: selectedArticle!.id,
      storageLocationId: location.id,
      ...(minimumLevelAmount.trim() ? { minimumLevelAmount: minimumLevelAmount.trim() } : {}),
      ...(minimumLevelAmount.trim() ? { minimumLevelUnit: UOM_VALUES[uomIdx] as string } : {}),
      ...(minimumShelfLifeDays.trim() ? { minimumShelfLifeDays: parseInt(minimumShelfLifeDays, 10) } : {}),
    });
    if (result) replace('stock-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();
    }
  };

  useInput((_input, key) => {
    if (loading) return;

    if (activeField === 'articleId') {
      if (key.escape) back();
      if (key.tab || key.downArrow) setActiveField('storageLocationId');
      if (key.return && selectedArticle && !articleQuery) setActiveField('storageLocationId');
      return;
    }

    if (activeField === 'storageLocationId') {
      if (key.upArrow) {
        if (locationIdx > 0) setLocationIdx((i) => i - 1);
        else setActiveField('articleId');
        return;
      }
      if (key.downArrow) {
        if (locationIdx < storageLocations.length - 1) setLocationIdx((i) => i + 1);
        else setActiveField('minimumLevelAmount');
        return;
      }
      if (key.return || key.tab) {
        setActiveField('minimumLevelAmount');
        return;
      }
      if (key.escape) back();
      return;
    }

    if (activeField === 'minimumLevelUnit') {
      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('minimumLevelUnit')('');
        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="Bestand wird angelegt..." />
      </Box>
    );
  }

  const uomLabel = UOM_LABELS[UOM_VALUES[uomIdx] as UoM] ?? UOM_VALUES[uomIdx];

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

      <Box flexDirection="column" gap={1} width={60}>
        {/* Article picker */}
        <Box flexDirection="column">
          <ArticlePicker
            articles={articles}
            query={articleQuery}
            onQueryChange={setArticleQuery}
            onSelect={handleArticleSelect}
            focus={activeField === 'articleId'}
            {...(selectedArticle ? { selectedName: selectedArticle.name } : {})}
          />
          {fieldErrors.articleId && <Text color="red">{fieldErrors.articleId}</Text>}
        </Box>

        {/* Storage location selector */}
        <Box flexDirection="column">
          <Text color={activeField === 'storageLocationId' ? 'cyan' : 'gray'}>{FIELD_LABELS.storageLocationId}</Text>
          {fieldErrors.storageLocationId && <Text color="red">{fieldErrors.storageLocationId}</Text>}
          <Box flexDirection="column" borderStyle="round" borderColor={activeField === 'storageLocationId' ? 'cyan' : 'gray'} paddingX={1}>
            {storageLocations.length === 0 ? (
              <Text color="gray" dimColor>Keine Lagerorte verfügbar.</Text>
            ) : (
              storageLocations.slice(Math.max(0, locationIdx - 3), locationIdx + 4).map((loc, i) => {
                const actualIdx = Math.max(0, locationIdx - 3) + i;
                const isSelected = actualIdx === locationIdx;
                return (
                  <Text key={loc.id} color={isSelected ? 'cyan' : 'white'}>
                    {isSelected ? '▶ ' : '  '}{loc.name} ({loc.storageType})
                  </Text>
                );
              })
            )}
          </Box>
        </Box>

        {/* Minimum level */}
        <FormInput
          label={FIELD_LABELS.minimumLevelAmount}
          value={minimumLevelAmount}
          onChange={setMinimumLevelAmount}
          onSubmit={handleFieldSubmit('minimumLevelAmount')}
          focus={activeField === 'minimumLevelAmount'}
          placeholder="optional"
        />

        <Box flexDirection="column">
          <Text color={activeField === 'minimumLevelUnit' ? 'cyan' : 'gray'}>
            {FIELD_LABELS.minimumLevelUnit}: <Text bold color="white">{activeField === 'minimumLevelUnit' ? `< ${uomLabel} >` : uomLabel}</Text>
          </Text>
        </Box>

        <FormInput
          label={FIELD_LABELS.minimumShelfLifeDays}
          value={minimumShelfLifeDays}
          onChange={setMinimumShelfLifeDays}
          onSubmit={handleFieldSubmit('minimumShelfLifeDays')}
          focus={activeField === 'minimumShelfLifeDays'}
          placeholder="optional, z.B. 30"
        />
      </Box>

      <Box marginTop={1}>
        <Text color="gray" dimColor>
          Tab/↑↓ Feld wechseln · ←→ Einheit · Enter bestätigen/speichern · Escape Abbrechen
        </Text>
      </Box>
    </Box>
  );
}
