import React, { useEffect, useState } from 'react';
import { Box, Text, useInput } from 'ink';
import { useNavigation } from '../../state/navigation-context.js';
import { useStockMovements } from '../../hooks/useStockMovements.js';
import { useStocks } from '../../hooks/useStocks.js';
import { FormInput } from '../shared/FormInput.js';
import { LoadingSpinner } from '../shared/LoadingSpinner.js';
import { ErrorDisplay } from '../shared/ErrorDisplay.js';
import { MOVEMENT_TYPE_LABELS, UOM_VALUES, UOM_LABELS } from '@effigenix/api-client';
import type { MovementType, UoM, StockDTO, StockBatchDTO, RecordStockMovementRequest } from '@effigenix/api-client';

const MOVEMENT_TYPES: MovementType[] = [
  'GOODS_RECEIPT', 'PRODUCTION_OUTPUT', 'PRODUCTION_CONSUMPTION',
  'SALE', 'RETURN', 'WASTE', 'ADJUSTMENT', 'INTER_BRANCH_TRANSFER',
];

type Field = 'stock' | 'batch' | 'movementType' | 'direction' | 'quantity' | 'unit' | 'reason' | 'referenceDocumentId';

const FIELD_LABELS: Record<Field, string> = {
  stock: 'Bestand (↑↓ auswählen)',
  batch: 'Charge (↑↓ auswählen)',
  movementType: 'Bewegungstyp (←→ wechseln)',
  direction: 'Richtung (←→ wechseln)',
  quantity: 'Menge *',
  unit: 'Einheit (←→ wechseln)',
  reason: 'Grund (bei Ausschuss/Korrektur)',
  referenceDocumentId: 'Referenz-Dok. (bei Umlagerung)',
};

const DIRECTIONS = ['IN', 'OUT'] as const;
const DIRECTION_LABELS: Record<string, string> = { IN: 'Eingang', OUT: 'Ausgang' };

function needsDirection(type: MovementType): boolean {
  return type === 'ADJUSTMENT';
}

function needsReason(type: MovementType): boolean {
  return type === 'WASTE' || type === 'ADJUSTMENT';
}

function needsReference(type: MovementType): boolean {
  return type === 'INTER_BRANCH_TRANSFER';
}

export function StockMovementRecordScreen() {
  const { back, params } = useNavigation();
  const { recordMovement, loading, error, clearError } = useStockMovements();
  const { stocks, fetchStocks } = useStocks();

  const preselectedStockId = params.stockId;

  const [stockIdx, setStockIdx] = useState(0);
  const [batchIdx, setBatchIdx] = useState(0);
  const [typeIdx, setTypeIdx] = useState(0);
  const [dirIdx, setDirIdx] = useState(0);
  const [quantity, setQuantity] = useState('');
  const [uomIdx, setUomIdx] = useState(0);
  const [reason, setReason] = useState('');
  const [refDocId, setRefDocId] = useState('');
  const [activeField, setActiveField] = useState<Field>(preselectedStockId ? 'batch' : 'stock');
  const [fieldErrors, setFieldErrors] = useState<Partial<Record<Field, string>>>({});
  const [success, setSuccess] = useState(false);

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

  useEffect(() => {
    if (preselectedStockId && stocks.length > 0) {
      const idx = stocks.findIndex((s) => s.id === preselectedStockId);
      if (idx >= 0) setStockIdx(idx);
    }
  }, [preselectedStockId, stocks]);

  const selectedStock: StockDTO | undefined = stocks[stockIdx];
  const batches: StockBatchDTO[] = selectedStock?.batches ?? [];
  const selectedBatch: StockBatchDTO | undefined = batches[batchIdx];
  const selectedType = MOVEMENT_TYPES[typeIdx]!;

  const getActiveFields = (): Field[] => {
    const fields: Field[] = ['stock', 'batch', 'movementType'];
    if (needsDirection(selectedType)) fields.push('direction');
    fields.push('quantity', 'unit');
    if (needsReason(selectedType)) fields.push('reason');
    if (needsReference(selectedType)) fields.push('referenceDocumentId');
    return fields;
  };

  const handleSubmit = async () => {
    const errors: Partial<Record<Field, string>> = {};
    if (!selectedStock) errors.stock = 'Bestand auswählen.';
    if (!selectedBatch) errors.batch = 'Charge auswählen.';
    if (!quantity.trim()) errors.quantity = 'Menge ist erforderlich.';
    if (needsDirection(selectedType) && !DIRECTIONS[dirIdx]) errors.direction = 'Richtung auswählen.';
    if (needsReason(selectedType) && !reason.trim()) errors.reason = 'Grund ist erforderlich.';
    if (needsReference(selectedType) && !refDocId.trim()) errors.referenceDocumentId = 'Referenz ist erforderlich.';
    setFieldErrors(errors);
    if (Object.keys(errors).length > 0) return;

    const request: Record<string, string> = {
      stockId: selectedStock!.id,
      articleId: selectedStock!.articleId,
      stockBatchId: selectedBatch!.id!,
      batchId: selectedBatch!.batchId!,
      batchType: selectedBatch!.batchType!,
      movementType: selectedType,
      quantityAmount: quantity.trim(),
      quantityUnit: UOM_VALUES[uomIdx] as string,
    };
    if (needsDirection(selectedType)) request.direction = DIRECTIONS[dirIdx];
    if (needsReason(selectedType) && reason.trim()) request.reason = reason.trim();
    if (needsReference(selectedType) && refDocId.trim()) request.referenceDocumentId = refDocId.trim();

    const result = await recordMovement(request as unknown as RecordStockMovementRequest);
    if (result) setSuccess(true);
  };

  const activeFields = getActiveFields();

  const goNextField = () => {
    const idx = activeFields.indexOf(activeField);
    if (idx < activeFields.length - 1) {
      setActiveField(activeFields[idx + 1]!);
    } else {
      void handleSubmit();
    }
  };

  const goPrevField = () => {
    const idx = activeFields.indexOf(activeField);
    if (idx > 0) setActiveField(activeFields[idx - 1]!);
  };

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

    if (success) {
      if (key.return || key.escape) back();
      return;
    }

    if (activeField === 'stock') {
      if (key.upArrow) setStockIdx((i) => Math.max(0, i - 1));
      if (key.downArrow) setStockIdx((i) => Math.min(stocks.length - 1, i + 1));
      if (key.return || key.tab) { setBatchIdx(0); goNextField(); }
      if (key.escape) back();
      return;
    }

    if (activeField === 'batch') {
      if (key.upArrow) setBatchIdx((i) => Math.max(0, i - 1));
      if (key.downArrow) setBatchIdx((i) => Math.min(batches.length - 1, i + 1));
      if (key.return || key.tab) goNextField();
      if (key.escape) goPrevField();
      return;
    }

    if (activeField === 'movementType') {
      if (key.leftArrow || key.rightArrow) {
        const dir = key.rightArrow ? 1 : -1;
        setTypeIdx((i) => (i + dir + MOVEMENT_TYPES.length) % MOVEMENT_TYPES.length);
        return;
      }
      if (key.return || key.tab) goNextField();
      if (key.escape) goPrevField();
      return;
    }

    if (activeField === 'direction') {
      if (key.leftArrow || key.rightArrow) {
        setDirIdx((i) => (i + 1) % DIRECTIONS.length);
        return;
      }
      if (key.return || key.tab) goNextField();
      if (key.escape) goPrevField();
      return;
    }

    if (activeField === 'unit') {
      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 || key.tab) goNextField();
      if (key.escape) goPrevField();
      return;
    }

    // Text-Felder
    if (key.tab || key.downArrow) goNextField();
    if (key.upArrow) goPrevField();
    if (key.escape) goPrevField();
  });

  if (loading) return <LoadingSpinner label="Bewegung wird erfasst..." />;

  if (success) {
    return (
      <Box flexDirection="column" gap={1} paddingY={1}>
        <Text color="green" bold>Bestandsbewegung erfolgreich erfasst!</Text>
        <Text color="gray" dimColor>Enter/Escape zum Zurückkehren</Text>
      </Box>
    );
  }

  const typeLabel = MOVEMENT_TYPE_LABELS[selectedType];
  const uomLabel = UOM_LABELS[UOM_VALUES[uomIdx] as UoM] ?? UOM_VALUES[uomIdx];
  const dirLabel = DIRECTION_LABELS[DIRECTIONS[dirIdx]] ?? DIRECTIONS[dirIdx];

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

      <Box flexDirection="column" gap={1} width={60}>
        {/* Stock selector */}
        <Box flexDirection="column">
          <Text color={activeField === 'stock' ? 'cyan' : 'gray'}>{FIELD_LABELS.stock}</Text>
          {fieldErrors.stock && <Text color="red">{fieldErrors.stock}</Text>}
          <Box flexDirection="column" borderStyle="round" borderColor={activeField === 'stock' ? 'cyan' : 'gray'} paddingX={1}>
            {stocks.length === 0 ? (
              <Text color="gray" dimColor>Keine Bestände gefunden.</Text>
            ) : (
              stocks.slice(Math.max(0, stockIdx - 3), stockIdx + 4).map((s, i) => {
                const actualIdx = Math.max(0, stockIdx - 3) + i;
                const isSelected = actualIdx === stockIdx;
                return (
                  <Text key={s.id} color={isSelected ? 'cyan' : 'white'}>
                    {isSelected ? '▶ ' : '  '}{s.articleId.substring(0, 12)} @ {s.storageLocationId.substring(0, 12)}
                  </Text>
                );
              })
            )}
          </Box>
        </Box>

        {/* Batch selector */}
        <Box flexDirection="column">
          <Text color={activeField === 'batch' ? 'cyan' : 'gray'}>{FIELD_LABELS.batch}</Text>
          {fieldErrors.batch && <Text color="red">{fieldErrors.batch}</Text>}
          <Box flexDirection="column" borderStyle="round" borderColor={activeField === 'batch' ? 'cyan' : 'gray'} paddingX={1}>
            {batches.length === 0 ? (
              <Text color="gray" dimColor>Keine Chargen in diesem Bestand.</Text>
            ) : (
              batches.slice(Math.max(0, batchIdx - 3), batchIdx + 4).map((b, i) => {
                const actualIdx = Math.max(0, batchIdx - 3) + i;
                const isSelected = actualIdx === batchIdx;
                return (
                  <Text key={b.id} color={isSelected ? 'cyan' : 'white'}>
                    {isSelected ? '▶ ' : '  '}{b.batchId} ({b.batchType}) – {b.quantityAmount} {b.quantityUnit}
                  </Text>
                );
              })
            )}
          </Box>
        </Box>

        {/* Movement Type */}
        <Box flexDirection="column">
          <Text color={activeField === 'movementType' ? 'cyan' : 'gray'}>
            {FIELD_LABELS.movementType}: <Text bold color="white">{activeField === 'movementType' ? `< ${typeLabel} >` : typeLabel}</Text>
          </Text>
        </Box>

        {/* Direction (only for ADJUSTMENT) */}
        {needsDirection(selectedType) && (
          <Box flexDirection="column">
            <Text color={activeField === 'direction' ? 'cyan' : 'gray'}>
              {FIELD_LABELS.direction}: <Text bold color="white">{activeField === 'direction' ? `< ${dirLabel} >` : dirLabel}</Text>
            </Text>
            {fieldErrors.direction && <Text color="red">{fieldErrors.direction}</Text>}
          </Box>
        )}

        {/* Quantity */}
        <FormInput
          label={FIELD_LABELS.quantity}
          value={quantity}
          onChange={setQuantity}
          onSubmit={() => goNextField()}
          focus={activeField === 'quantity'}
          {...(fieldErrors.quantity ? { error: fieldErrors.quantity } : {})}
        />

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

        {/* Reason (for WASTE/ADJUSTMENT) */}
        {needsReason(selectedType) && (
          <FormInput
            label={FIELD_LABELS.reason}
            value={reason}
            onChange={setReason}
            onSubmit={() => goNextField()}
            focus={activeField === 'reason'}
            {...(fieldErrors.reason ? { error: fieldErrors.reason } : {})}
          />
        )}

        {/* Reference Document ID (for INTER_BRANCH_TRANSFER) */}
        {needsReference(selectedType) && (
          <FormInput
            label={FIELD_LABELS.referenceDocumentId}
            value={refDocId}
            onChange={setRefDocId}
            onSubmit={() => void handleSubmit()}
            focus={activeField === 'referenceDocumentId'}
            {...(fieldErrors.referenceDocumentId ? { error: fieldErrors.referenceDocumentId } : {})}
          />
        )}
      </Box>

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