import { useState } from 'react';
import { Box, Text, useInput } from 'ink';
import { useNavigation } from '../../state/navigation-context.js';
import { FormInput } from '../shared/FormInput.js';
import { LoadingSpinner } from '../shared/LoadingSpinner.js';
import { ErrorDisplay } from '../shared/ErrorDisplay.js';
import { SuccessDisplay } from '../shared/SuccessDisplay.js';
import { useStocks } from '../../hooks/useStocks.js';
import { BATCH_TYPE_LABELS, UOM_VALUES, UOM_LABELS } from '@effigenix/api-client';
import type { BatchType, UoM } from '@effigenix/api-client';

type Field = 'batchId' | 'batchType' | 'quantityAmount' | 'quantityUnit' | 'expiryDate';
const FIELDS: Field[] = ['batchId', 'batchType', 'quantityAmount', 'quantityUnit', 'expiryDate'];

const FIELD_LABELS: Record<Field, string> = {
  batchId: 'Chargen-Nr. *',
  batchType: 'Chargentyp *',
  quantityAmount: 'Menge *',
  quantityUnit: 'Einheit * (←→ wechseln)',
  expiryDate: 'Ablaufdatum (YYYY-MM-DD) *',
};

const BATCH_TYPES: BatchType[] = ['PURCHASED', 'PRODUCED'];

export function AddBatchScreen() {
  const { params, replace, back } = useNavigation();
  const stockId = params['stockId'] ?? '';

  const { addBatch, loading, error, clearError } = useStocks();

  const [values, setValues] = useState<Record<Exclude<Field, 'quantityUnit'>, string>>({
    batchId: '', batchType: 'PURCHASED', quantityAmount: '', expiryDate: '',
  });
  const [uomIdx, setUomIdx] = useState(0);
  const [activeField, setActiveField] = useState<Field>('batchId');
  const [fieldErrors, setFieldErrors] = useState<Partial<Record<Field, string>>>({});
  const [success, setSuccess] = useState<string | null>(null);

  const setField = (field: Exclude<Field, 'quantityUnit'>) => (value: string) => {
    setValues((v) => ({ ...v, [field]: value }));
  };

  const handleSubmit = async () => {
    const errors: Partial<Record<Field, string>> = {};
    if (!values.batchId.trim()) errors.batchId = 'Chargen-Nr. ist erforderlich.';
    if (!values.quantityAmount.trim()) errors.quantityAmount = 'Menge ist erforderlich.';
    if (values.quantityAmount.trim() && isNaN(Number(values.quantityAmount))) errors.quantityAmount = 'Muss eine Zahl sein.';
    if (!values.expiryDate.trim()) errors.expiryDate = 'Ablaufdatum ist erforderlich.';
    if (values.expiryDate.trim() && !/^\d{4}-\d{2}-\d{2}$/.test(values.expiryDate.trim())) {
      errors.expiryDate = 'Format: YYYY-MM-DD';
    }
    setFieldErrors(errors);
    if (Object.keys(errors).length > 0) return;

    const selectedUom = UOM_VALUES[uomIdx] as UoM;
    const batch = await addBatch(stockId, {
      batchId: values.batchId.trim(),
      batchType: values.batchType,
      quantityAmount: values.quantityAmount.trim(),
      quantityUnit: selectedUom,
      expiryDate: values.expiryDate.trim(),
    });

    if (batch) {
      setSuccess(`Charge ${batch.batchId} erfolgreich eingebucht.`);
    }
  };

  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 === 'batchType') {
      if (key.leftArrow || key.rightArrow) {
        const idx = BATCH_TYPES.indexOf(values.batchType as BatchType);
        const next = key.rightArrow
          ? BATCH_TYPES[(idx + 1) % BATCH_TYPES.length]
          : BATCH_TYPES[(idx - 1 + BATCH_TYPES.length) % BATCH_TYPES.length];
        if (next) setValues((v) => ({ ...v, batchType: next }));
        return;
      }
      if (key.return) {
        handleFieldSubmit('batchType')('');
        return;
      }
    }

    if (activeField === 'quantityUnit') {
      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('quantityUnit')('');
        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 (!stockId) return <ErrorDisplay message="Keine Bestand-ID vorhanden." onDismiss={back} />;
  if (loading) return <Box paddingY={2}><LoadingSpinner label="Charge wird eingebucht..." /></Box>;

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

  return (
    <Box flexDirection="column" gap={1}>
      <Text color="cyan" bold>Charge einbuchen</Text>
      {error && <ErrorDisplay message={error} onDismiss={clearError} />}
      {success && <SuccessDisplay message={success} onDismiss={() => replace('inventory-menu')} />}

      {!success && (
        <Box flexDirection="column" gap={1} width={60}>
          {FIELDS.map((field) => {
            if (field === 'batchType') {
              const typeName = BATCH_TYPE_LABELS[values.batchType as BatchType] ?? values.batchType;
              return (
                <Box key={field} flexDirection="column">
                  <Text color={activeField === field ? 'cyan' : 'gray'}>
                    {FIELD_LABELS[field]}: {activeField === field ? `< ${typeName} >` : typeName}
                  </Text>
                </Box>
              );
            }
            if (field === 'quantityUnit') {
              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>
              );
            }
            return (
              <FormInput
                key={field}
                label={FIELD_LABELS[field]}
                value={values[field as Exclude<Field, 'quantityUnit'>]}
                onChange={setField(field as Exclude<Field, 'quantityUnit'>)}
                onSubmit={handleFieldSubmit(field)}
                focus={activeField === field}
                {...(fieldErrors[field] ? { error: fieldErrors[field] } : {})}
              />
            );
          })}
        </Box>
      )}

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