import { BottomSheet, BottomSheetTextInput } from '@/aesthetics/BottomSheet';
import { Text } from '@/aesthetics/Text';
import { buttonHeight, font, radius, spacing, useColors } from '@/aesthetics/styles';
import { useHaptics } from '@/aesthetics/useHaptics';
import { useStrings } from '@/common/hooks/useStrings';
import { useState, useCallback } from 'react';
import { Pressable, StyleSheet, View } from 'react-native';
import { X } from 'lucide-react-native';
import { TYPE_OPTION_KEYS, TYPE_ICONS, NUMBER_UNITS } from './constants';
import type { InputType, MemoLogger, MemoLoggerOption } from './types';

type Props = {
  visible: boolean;
  onClose: () => void;
  onCreate: (logger: Omit<MemoLogger, 'id'>) => void;
  onUpdate?: (id: string, updates: Partial<Omit<MemoLogger, 'id'>>) => void;
  onOpenIconPicker: (index: number, onSelect: (icon: string) => void) => void;
  logger?: MemoLogger;
};

export function MemoLoggerEditor({
  visible,
  onClose,
  onCreate,
  onUpdate,
  onOpenIconPicker,
  logger,
}: Props) {
  const c = useColors();
  const strings = useStrings();
  const { selection } = useHaptics();

  const typeLabels: Record<InputType, string> = {
    singleselect: strings.userCustomLogs.types.select,
    multiselect: strings.userCustomLogs.types.multi,
    text: strings.userCustomLogs.types.text,
    number: strings.userCustomLogs.types.number,
    check: strings.userCustomLogs.types.check,
  };

  const createInitialOptions = (): MemoLoggerOption[] => [
    { label: strings.userCustomLogs.optionPlaceholder(1), icon: '1️⃣' },
    { label: strings.userCustomLogs.optionPlaceholder(2), icon: '2️⃣' },
    { label: strings.userCustomLogs.optionPlaceholder(3), icon: '3️⃣' },
  ];

  const [name, setName] = useState('');
  const [icon, setIcon] = useState<string | undefined>();
  const [type, setType] = useState<InputType>('text');
  const [options, setOptions] = useState<MemoLoggerOption[]>(createInitialOptions);
  const [unit, setUnit] = useState('');
  const [unitType, setUnitType] = useState('plain');

  const isEditing = !!logger;
  const [prevLogger, setPrevLogger] = useState(logger);

  if (logger !== prevLogger) {
    setPrevLogger(logger);
    if (logger) {
      setName(logger.name);
      setIcon(logger.icon);
      setType(logger.type);
      setOptions(logger.options?.length ? logger.options : createInitialOptions());
      setUnit(logger.unit ?? '');
      setUnitType(logger.unit ? 'custom' : 'plain');
    }
  }

  const reset = () => {
    setName('');
    setIcon(undefined);
    setType('text');
    setOptions(createInitialOptions());
    setUnit('');
    setUnitType('plain');
  };

  const handleClose = () => {
    reset();
    onClose();
  };

  const handleSave = () => {
    if (!name.trim()) return;
    const isSelect = type === 'singleselect' || type === 'multiselect';
    const data = {
      name: name.trim(),
      icon,
      type,
      unit: type === 'number' ? unit || undefined : undefined,
      options: isSelect ? options : undefined,
    };
    if (isEditing && onUpdate) {
      onUpdate(logger.id, data);
    } else {
      onCreate(data);
    }
    reset();
  };

  const handleLoggerIconPress = useCallback(() => {
    onOpenIconPicker(-1, setIcon);
  }, [onOpenIconPicker]);

  const handleIconPress = useCallback(
    (index: number) => {
      onOpenIconPicker(index, (icon: string) => {
        setOptions(prev => {
          const updated = [...prev];
          updated[index] = { ...updated[index], icon };
          return updated;
        });
      });
    },
    [onOpenIconPicker]
  );

  const updateOptionLabel = (index: number, label: string) => {
    setOptions(prev => {
      const updated = [...prev];
      updated[index] = { ...updated[index], label };
      return updated;
    });
  };

  const addOption = () => {
    setOptions(prev => [
      ...prev,
      { label: strings.userCustomLogs.optionPlaceholder(prev.length + 1), icon: '⭐' },
    ]);
  };

  const removeOption = (index: number) => {
    setOptions(prev => prev.filter((_, i) => i !== index));
  };

  const selectUnit = (id: string, unitValue: string) => {
    setUnitType(id);
    setUnit(unitValue);
  };

  const isSelect = type === 'singleselect' || type === 'multiselect';

  return (
    <BottomSheet
      visible={visible}
      onClose={handleClose}
      title={isEditing ? strings.userCustomLogs.editLogger : strings.userCustomLogs.newLogger}
    >
      <View style={styles.container}>
        <Text style={[styles.label, { color: c.secondaryText }]}>
          {strings.userCustomLogs.loggerName}
        </Text>
        <View style={styles.nameRow}>
          <Pressable
            onPress={handleLoggerIconPress}
            style={[styles.loggerIconBtn, { backgroundColor: c.tagBg }]}
          >
            <Text style={styles.loggerIconText}>{icon || '📝'}</Text>
          </Pressable>
          <BottomSheetTextInput
            style={[styles.input, styles.nameInput, { backgroundColor: c.tagBg, color: c.text }]}
            placeholder={strings.userCustomLogs.loggerNamePlaceholder}
            placeholderTextColor={c.tertiaryText}
            value={name}
            onChangeText={setName}
            autoFocus
          />
        </View>

        <Text style={[styles.label, { color: c.secondaryText }]}>
          {strings.userCustomLogs.type}
        </Text>
        <View style={styles.typeRow}>
          {TYPE_OPTION_KEYS.map(typeKey => {
            const Icon = TYPE_ICONS[typeKey];
            const selected = type === typeKey;
            return (
              <Pressable
                key={typeKey}
                onPress={() => {
                  selection();
                  setType(typeKey);
                }}
                style={[styles.typeOption, { backgroundColor: selected ? c.accent : c.tagBg }]}
              >
                <Icon size={20} color={selected ? c.onAccent : c.tertiaryText} strokeWidth={2} />
                <Text
                  style={[
                    styles.typeOptionLabel,
                    { color: selected ? c.onAccent : c.secondaryText },
                  ]}
                >
                  {typeLabels[typeKey]}
                </Text>
              </Pressable>
            );
          })}
        </View>

        {isSelect && (
          <View style={styles.optionsEditor}>
            {options.map((opt, i) => (
              <View key={i} style={styles.optionRow}>
                <Pressable
                  onPress={() => handleIconPress(i)}
                  style={[styles.iconBtn, { backgroundColor: c.tagBg }]}
                >
                  <Text style={styles.iconBtnText}>{opt.icon}</Text>
                </Pressable>
                <BottomSheetTextInput
                  style={[styles.optionInput, { backgroundColor: c.tagBg, color: c.text }]}
                  value={opt.label}
                  onChangeText={text => updateOptionLabel(i, text)}
                  placeholder={strings.userCustomLogs.optionPlaceholder(i + 1)}
                  placeholderTextColor={c.tertiaryText}
                />
                {options.length > 2 && (
                  <Pressable onPress={() => removeOption(i)} style={styles.removeBtn}>
                    <X size={14} color={c.danger} strokeWidth={2.5} />
                  </Pressable>
                )}
              </View>
            ))}
            {options.length < 10 && (
              <Pressable
                onPress={addOption}
                style={[styles.addOptionBtn, { backgroundColor: c.tagBg }]}
              >
                <Text style={{ color: c.tertiaryText }}>{strings.userCustomLogs.addOption}</Text>
              </Pressable>
            )}
          </View>
        )}

        {type === 'number' && (
          <>
            <Text style={[styles.label, { color: c.secondaryText }]}>
              {strings.userCustomLogs.unit}
            </Text>
            <View style={styles.unitRow}>
              {NUMBER_UNITS.map(u => (
                <Pressable
                  key={u.id}
                  onPress={() => {
                    selection();
                    selectUnit(u.id, u.unit);
                  }}
                  style={[
                    styles.unitChip,
                    { backgroundColor: unitType === u.id ? c.accent : c.tagBg },
                  ]}
                >
                  <Text
                    style={[styles.unitLabel, { color: unitType === u.id ? c.onAccent : c.text }]}
                  >
                    {u.label}
                  </Text>
                </Pressable>
              ))}
            </View>
            <BottomSheetTextInput
              style={[styles.input, { backgroundColor: c.tagBg, color: c.text }]}
              placeholder={strings.userCustomLogs.customUnit}
              placeholderTextColor={c.tertiaryText}
              value={unit}
              onChangeText={setUnit}
            />
          </>
        )}

        <Pressable
          onPress={handleSave}
          disabled={!name.trim()}
          style={[styles.createBtn, { backgroundColor: c.accent }, !name.trim() && styles.disabled]}
        >
          <Text style={[styles.createLabel, { color: c.onAccent }]}>
            {isEditing ? strings.userCustomLogs.saveLogger : strings.userCustomLogs.createLogger}
          </Text>
        </Pressable>
      </View>
    </BottomSheet>
  );
}

const styles = StyleSheet.create({
  container: { gap: spacing.lg },
  label: { fontSize: font.md, fontWeight: '600', marginBottom: -spacing.sm },
  nameRow: { flexDirection: 'row', gap: spacing.sm },
  loggerIconBtn: {
    width: 48,
    height: 48,
    borderRadius: radius.md,
    alignItems: 'center',
    justifyContent: 'center',
  },
  loggerIconText: { fontSize: 24 },
  input: {
    paddingVertical: spacing.md,
    paddingHorizontal: spacing.lg,
    borderRadius: radius.md,
    fontSize: font.md,
  },
  nameInput: { flex: 1 },
  typeRow: { flexDirection: 'row', gap: spacing.xs },
  typeOption: {
    flex: 1,
    minHeight: buttonHeight.lg,
    paddingVertical: spacing.sm,
    borderRadius: radius.md,
    alignItems: 'center',
    justifyContent: 'center',
    gap: 4,
  },
  typeOptionLabel: { fontSize: font.xs, fontWeight: '500' },
  optionsEditor: { gap: spacing.sm },
  optionRow: { flexDirection: 'row', alignItems: 'center', gap: spacing.sm },
  iconBtn: {
    width: 40,
    height: 40,
    borderRadius: radius.md,
    alignItems: 'center',
    justifyContent: 'center',
  },
  iconBtnText: { fontSize: 20 },
  optionInput: {
    flex: 1,
    paddingVertical: spacing.sm,
    paddingHorizontal: spacing.md,
    borderRadius: radius.md,
    fontSize: font.sm,
  },
  removeBtn: { padding: spacing.sm },
  addOptionBtn: {
    paddingVertical: spacing.sm,
    paddingHorizontal: spacing.md,
    borderRadius: radius.md,
    alignItems: 'center',
  },
  unitRow: { flexDirection: 'row', gap: spacing.sm },
  unitChip: {
    flex: 1,
    minHeight: buttonHeight.sm,
    paddingVertical: spacing.sm,
    borderRadius: radius.md,
    alignItems: 'center',
    justifyContent: 'center',
  },
  unitLabel: { fontSize: font.sm, fontWeight: '600' },
  createBtn: {
    minHeight: buttonHeight.md,
    paddingVertical: spacing.md,
    borderRadius: radius.md,
    alignItems: 'center',
    justifyContent: 'center',
  },
  createLabel: { fontSize: font.md, fontWeight: '600' },
  disabled: { opacity: 0.4 },
});
