/**
 * 通用模态表单（plan.md 管理页 CRUD）。
 *
 * 底部弹出的模态对话框，包含多个文本输入字段 + 确认/取消按钮。
 * 供分类/标签/预算/信用卡/规则管理页的「添加/编辑」复用。
 *
 * 拆分说明：
 * - 字段渲染拆分为 TextField / SelectField / DropdownField 子组件（见 formFields.tsx）
 * - 下拉菜单不再使用嵌套 Modal，改为同层 overlay，避免 Android z-index/返回键冲突
 */

import React, { useEffect, useMemo, useState } from 'react';
import { Modal, Pressable, ScrollView, StyleSheet, Text, View } from 'react-native';
import { SafeAreaProvider, useSafeAreaInsets } from 'react-native-safe-area-context';
import { Ionicons } from '@expo/vector-icons';
import { useTheme, createCommonStyles } from '../../theme';
import { useT } from '../../i18n';
import { useKeyboardHeight } from '../../hooks/useKeyboardAvoiding';
import { Button } from '../ui/Button';
import { Touchable } from '../ui/Touchable';
import { TextField, SelectField, DropdownField, DropdownMenu } from './FormFields';

export interface FormOption {
  label: string;
  value: string;
  subLabel?: string;
}

export interface FormField {
  key: string;
  label: string;
  placeholder?: string;
  defaultValue?: string;
  keyboardType?: 'default' | 'numeric' | 'decimal-pad' | 'phone-pad';
  multiline?: boolean;
  secureTextEntry?: boolean;
  type?: 'text' | 'select' | 'dropdown';
  options?: FormOption[];
  flex?: number;
  row?: number;
}

interface FormModalProps {
  visible: boolean;
  title: string;
  fields: FormField[];
  onConfirm: (values: Record<string, string>) => void;
  onCancel: () => void;
  confirmLabel?: string;
  onValuesChange?: (changedKey: string, newValue: string, prevValues: Record<string, string>) => Record<string, string> | void;
  children?: React.ReactNode;
}

/**
 * 外层：Modal + SafeAreaProvider 包裹。
 * 关键：RN <Modal> 会脱离主窗口的 SafeAreaProvider context，导致内部
 * useSafeAreaInsets() 返回全 0、KeyboardAvoidingView 失效。
 * 故在 Modal 内重新包一层 SafeAreaProvider，让内层弹窗恢复 SafeArea 与键盘避让能力。
 */
export function FormModal(props: FormModalProps) {
  return (
    <Modal visible={props.visible} transparent animationType="slide" onRequestClose={props.onCancel}>
      <SafeAreaProvider>
        <FormModalContent {...props} />
      </SafeAreaProvider>
    </Modal>
  );
}

function FormModalContent({ visible, title, fields, onConfirm, onCancel, confirmLabel, onValuesChange, children }: FormModalProps) {
  const { theme } = useTheme();
  const t = useT();
  const insets = useSafeAreaInsets();
  const bottomInset = insets.bottom;
  // 响应式键盘避让：键盘高度做 paddingBottom（参考 BeeCount AnimatedPadding 方案）。
  // 键盘弹出 → paddingBottom 增大顶起内容；关闭 → 回到基础留白，无残留。
  const kbHeight = useKeyboardHeight();
  const commonStyles = useMemo(() => createCommonStyles(theme), [theme]);
  /* eslint-disable react-native/no-unused-styles */
  const styles = useMemo(() => StyleSheet.create({
    overlay: { flex: 1, justifyContent: 'flex-end' },
    // paddingBottom 取「安全区」与「最小视觉留白 24」的较大值，二者不叠加
    // （安全区已包含手势条区域，叠加 36 会导致底部空白过大）
    sheet: { maxHeight: '80%', padding: 20, paddingTop: 12, paddingBottom: Math.max(bottomInset, 24), borderTopLeftRadius: theme.radii.xl, borderTopRightRadius: theme.radii.xl },
    dragHandle: { width: 36, height: 4, borderRadius: 2, alignSelf: 'center', marginBottom: theme.spacing.md, opacity: 0.8 },
    header: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', marginBottom: theme.spacing.md },
    closeCircleBtn: { width: 32, height: 32, borderRadius: theme.radii.full, alignItems: 'center', justifyContent: 'center' },
    body: { maxHeight: 400 },
    rowFieldGroup: { flexDirection: 'row', gap: 12 },
    actions: { flexDirection: 'row', marginTop: theme.spacing.md },
    // 下拉菜单同层 overlay（替代嵌套 Modal）
    menuOverlay: { position: 'absolute', top: 0, left: 0, right: 0, bottom: 0, justifyContent: 'center', alignItems: 'center', padding: 24 },
    dropdownMenu: { width: '100%', maxHeight: 320, borderRadius: theme.radii.lg, borderWidth: 1, overflow: 'hidden' },
  }), [theme, bottomInset]); // eslint-disable-line react-hooks/exhaustive-deps
  /* eslint-enable react-native/no-unused-styles */

  const [values, setValues] = useState<Record<string, string>>({});
  const [activeDropdownKey, setActiveDropdownKey] = useState<string | null>(null);
  const [focusedKey, setFocusedKey] = useState<string | null>(null);

  const updateFieldValue = (key: string, val: string) => {
    setValues(prev => {
      const next = { ...prev, [key]: val };
      if (onValuesChange) {
        const overridden = onValuesChange(key, val, next);
        return overridden ? { ...next, ...overridden } : next;
      }
      return next;
    });
  };

  useEffect(() => {
    if (visible) {
      const init: Record<string, string> = {};
      for (const f of fields) {
        init[f.key] = f.defaultValue ?? '';
      }
      setValues(init);
      setActiveDropdownKey(null);
      setFocusedKey(null);
    }
  }, [visible]); // eslint-disable-line react-hooks/exhaustive-deps

  // 渲染单个字段（委托给子组件）
  const renderField = (f: FormField) => {
    const isFocused = focusedKey === f.key || activeDropdownKey === f.key;

    if (f.type === 'dropdown' && f.options) {
      return (
        <DropdownField
          key={f.key}
          field={f}
          value={values[f.key] ?? ''}
          isFocused={isFocused}
          onOpen={() => setActiveDropdownKey(f.key)}
          theme={theme}
          commonStyles={commonStyles}
        />
      );
    }

    if (f.type === 'select' && f.options) {
      return (
        <SelectField
          key={f.key}
          field={f}
          value={values[f.key] ?? ''}
          onSelect={(v) => updateFieldValue(f.key, v)}
          theme={theme}
        />
      );
    }

    return (
      <TextField
        key={f.key}
        field={f}
        value={values[f.key] ?? ''}
        onChangeText={(text) => updateFieldValue(f.key, text)}
        isFocused={isFocused}
        onFocus={() => setFocusedKey(f.key)}
        onBlur={() => setFocusedKey(null)}
        theme={theme}
        commonStyles={commonStyles}
      />
    );
  };

  // 分组具有 flex 且相同 row 的连续字段
  const fieldElements: React.ReactNode[] = [];
  let flexGroup: FormField[] = [];
  let currentGroupRow: number | undefined = undefined;

  const flushFlexGroup = () => {
    if (flexGroup.length > 0) {
      fieldElements.push(
        <View key={'row-' + flexGroup[0].key} style={styles.rowFieldGroup}>
          {flexGroup.map(renderField)}
        </View>
      );
      flexGroup = [];
    }
  };

  for (const f of fields) {
    if (f.flex) {
      const fieldRow = f.row ?? 1;
      if (flexGroup.length > 0 && currentGroupRow !== fieldRow) {
        flushFlexGroup();
      }
      currentGroupRow = fieldRow;
      flexGroup.push(f);
    } else {
      flushFlexGroup();
      currentGroupRow = undefined;
      fieldElements.push(renderField(f));
    }
  }
  flushFlexGroup();

  const activeField = fields.find(f => f.key === activeDropdownKey);

  return (
    <View style={styles.overlay}>
      <Pressable style={[styles.overlay, { backgroundColor: theme.colors.overlay }]} onPress={onCancel}>
        <Pressable
          style={[
            styles.sheet,
            theme.shadows.lg,
            {
              backgroundColor: theme.colors.bgSecondary,
              borderColor: theme.colors.border,
              // 响应式 paddingBottom：基础留白(取安全区与24较大值) + 键盘高度
              paddingBottom: Math.max(bottomInset, 24) + kbHeight,
            },
          ]}
          onPress={(e) => e.stopPropagation()}
        >
          {/* 顶部 Drag Handle */}
          <View style={[styles.dragHandle, { backgroundColor: theme.colors.divider }]} />

          <View style={styles.header}>
            <Text style={[theme.typography.h3, { color: theme.colors.fgPrimary, fontWeight: '700' }]}>{title}</Text>
            <Touchable onPress={onCancel} hitSlop={8} style={[styles.closeCircleBtn, { backgroundColor: theme.colors.bgTertiary }]}>
              <Ionicons name="close" size={16} color={theme.colors.fgSecondary} />
            </Touchable>
          </View>

          <ScrollView style={styles.body} showsVerticalScrollIndicator={false} keyboardShouldPersistTaps="handled" keyboardDismissMode="interactive">
            {fieldElements}
          </ScrollView>

          {children}
          <View style={styles.actions}>
            <Button label={t('common.cancel')} onPress={onCancel} variant="secondary" />
            <View style={{ flex: 1 }} />
            <Button label={confirmLabel ?? t('common.confirm')} onPress={() => onConfirm(values)} />
          </View>
        </Pressable>
      </Pressable>

      {/* 下拉菜单同层 overlay（替代嵌套 Modal，避免 Android z-index/返回键冲突） */}
      {activeDropdownKey !== null && activeField && (
        <Pressable style={[styles.menuOverlay, { backgroundColor: theme.colors.overlay }]} onPress={() => setActiveDropdownKey(null)}>
          <Pressable
            style={[styles.dropdownMenu, theme.shadows.lg, { backgroundColor: theme.colors.bgSecondary, borderColor: theme.colors.border }]}
            onPress={e => e.stopPropagation()}
          >
            <DropdownMenu
              field={activeField}
              value={values[activeField.key] ?? ''}
              onSelect={(v) => updateFieldValue(activeField.key, v)}
              onClose={() => setActiveDropdownKey(null)}
              theme={theme}
            />
          </Pressable>
        </Pressable>
      )}
    </View>
  );
}
