import React, { useCallback, useEffect, useState } from 'react';
import { Box, Text, useInput } from 'ink';
import type { StorageLocationDTO, StorageType } from '@effigenix/api-client';
import { STORAGE_TYPE_LABELS } from '@effigenix/api-client';
import { useNavigation } from '../../state/navigation-context.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 { client } from '../../utils/api-client.js';

type Field = 'name' | 'minTemperature' | 'maxTemperature';
const FIELDS: Field[] = ['name', 'minTemperature', 'maxTemperature'];

const FIELD_LABELS: Record<Field, string> = {
  name: 'Name',
  minTemperature: 'Min. Temperatur (°C)',
  maxTemperature: 'Max. Temperatur (°C)',
};

function errorMessage(err: unknown): string {
  return err instanceof Error ? err.message : 'Unbekannter Fehler';
}

export function StorageLocationEditScreen() {
  const { params, replace, back } = useNavigation();
  const storageLocationId = params['storageLocationId'] ?? '';
  const { updateStorageLocation } = useStorageLocations();

  const [location, setLocation] = useState<StorageLocationDTO | null>(null);
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [values, setValues] = useState<Record<Field, string>>({
    name: '',
    minTemperature: '',
    maxTemperature: '',
  });
  const [activeField, setActiveField] = useState<Field>('name');
  const [fieldErrors, setFieldErrors] = useState<Partial<Record<Field, string>>>({});

  const loadLocation = useCallback(() => {
    setLoading(true);
    setError(null);
    client.storageLocations.getById(storageLocationId)
      .then((loc) => {
        setLocation(loc);
        setValues({
          name: loc.name,
          minTemperature: loc.temperatureRange?.minTemperature?.toString() ?? '',
          maxTemperature: loc.temperatureRange?.maxTemperature?.toString() ?? '',
        });
        setLoading(false);
      })
      .catch((err: unknown) => { setError(errorMessage(err)); setLoading(false); });
  }, [storageLocationId]);

  useEffect(() => { if (storageLocationId) loadLocation(); }, [loadLocation, storageLocationId]);

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

  useInput((_input, key) => {
    if (loading || saving) 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();
  });

  const handleSubmit = async () => {
    const errors: Partial<Record<Field, string>> = {};
    if (!values.name.trim()) errors.name = 'Name ist erforderlich.';
    setFieldErrors(errors);
    if (Object.keys(errors).length > 0) return;

    setSaving(true);
    setError(null);
    const result = await updateStorageLocation(storageLocationId, {
      ...(values.name.trim() ? { name: values.name.trim() } : {}),
      ...(values.minTemperature.trim() ? { minTemperature: values.minTemperature.trim() } : {}),
      ...(values.maxTemperature.trim() ? { maxTemperature: values.maxTemperature.trim() } : {}),
    });
    setSaving(false);

    if (result) {
      replace('storage-location-detail', { storageLocationId });
    } else {
      setError('Speichern fehlgeschlagen.');
    }
  };

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

  if (loading) return <LoadingSpinner label="Lade Lagerort..." />;
  if (error && !location) return <ErrorDisplay message={error} onDismiss={back} />;
  if (!location) return <Text color="red">Lagerort nicht gefunden.</Text>;

  const typeName = STORAGE_TYPE_LABELS[location.storageType as StorageType] ?? location.storageType;

  if (saving) {
    return (
      <Box flexDirection="column" alignItems="center" paddingY={2}>
        <LoadingSpinner label="Lagerort wird gespeichert..." />
      </Box>
    );
  }

  return (
    <Box flexDirection="column" gap={1}>
      <Text color="cyan" bold>Lagerort bearbeiten: {location.name}</Text>
      {error && <ErrorDisplay message={error} onDismiss={() => setError(null)} />}

      <Box gap={2}>
        <Text color="gray">Lagertyp:</Text>
        <Text>{typeName}</Text>
        <Text color="gray" dimColor>(nicht änderbar)</Text>
      </Box>

      <Box flexDirection="column" gap={1} width={60}>
        {FIELDS.map((field) => (
          <FormInput
            key={field}
            label={FIELD_LABELS[field]}
            value={values[field]}
            onChange={setField(field)}
            onSubmit={handleFieldSubmit(field)}
            focus={activeField === field}
            {...(fieldErrors[field] ? { error: fieldErrors[field] } : {})}
          />
        ))}
      </Box>

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