﻿/**
 * 通用模态表单（plan.md 管理页 CRUD）。
 *
 * 底部弹出的模态对话框,包含多个文本输入字段 + 确认/取消按钮。
 * 供分类/标签/预算/信用卡/规则管理页的「添加/编辑」复用。
 *
 * 用法:
 * <FormModal
 *   visible={true}
 *   title="添加分类"
 *   fields={[
 *     { key: 'name', label: '名称', placeholder: '餐饮' },
 *     { key: 'linkedAccount', label: '关联账户', placeholder: 'Expenses:餐饮' },
 *   ]}
 *   initialValues={{ name: '', linkedAccount: '' }}
 *   onConfirm={(values) => { /* 保存 *\/ }}
 *   onCancel={() => { /* 关闭 *\/ }}
 * />
 */

import React, { useEffect, useMemo, useState } from 'react';
import { Modal, Pressable, ScrollView, StyleSheet, Text, TextInput, View } from 'react-native';
import { useTheme, createCommonStyles } from '../theme';
import { useT } from '../i18n';
import { Button } from './Button';

export interface FormField {
  /** 字段 key,对应 values 对象的属性名。 */
  key: string;
  /** 显示标签。 */
  label: string;
  /** 占位提示。 */
  placeholder?: string;
  /** 默认值(新增时为空,编辑时预填)。 */
  defaultValue?: string;
  /** 键盘类型。 */
  keyboardType?: 'default' | 'numeric' | 'decimal-pad' | 'phone-pad';
  /** 多行输入。 */
  multiline?: boolean;
  /** 密码输入（遮蔽文本）。 */
  secureTextEntry?: boolean;
}

interface FormModalProps {
  visible: boolean;
  title: string;
  fields: FormField[];
  onConfirm: (values: Record<string, string>) => void;
  onCancel: () => void;
  /** 确认按钮文本(默认「确定」)。 */
  confirmLabel?: string;
}

export function FormModal({ visible, title, fields, onConfirm, onCancel, confirmLabel }: FormModalProps) {
  const { theme } = useTheme();
  const t = useT();
  const commonStyles = useMemo(() => createCommonStyles(theme), [theme]);
  const [values, setValues] = useState<Record<string, string>>({});

  // 每次 visible 变为 true 时,用 fields 的 defaultValue 初始化
  useEffect(() => {
    if (visible) {
      const init: Record<string, string> = {};
      for (const f of fields) {
        init[f.key] = f.defaultValue ?? '';
      }
      setValues(init);
    }
  }, [visible]); // eslint-disable-line react-hooks/exhaustive-deps

  return (
    <Modal visible={visible} transparent animationType="slide" onRequestClose={onCancel}>
      <Pressable style={[styles.overlay, { backgroundColor: theme.colors.overlay }]} onPress={onCancel}>
        <Pressable
          style={[styles.sheet, {
            backgroundColor: theme.colors.bgSecondary,
            borderRadius: theme.radii.lg,
            borderWidth: StyleSheet.hairlineWidth,
            borderColor: theme.colors.border,
          }]}
          onPress={(e) => e.stopPropagation()}
        >
          <View style={[styles.header, { borderBottomColor: theme.colors.divider }]}>
            <Text style={[theme.typography.h3, { color: theme.colors.fgPrimary }]}>{title}</Text>
            <Pressable onPress={onCancel} hitSlop={8}>
              <Text style={[theme.typography.body, { color: theme.colors.fgSecondary }]}>✕</Text>
            </Pressable>
          </View>

          <ScrollView style={styles.body}>
            {fields.map(f => (
              <View key={f.key} style={styles.field}>
                <Text style={[theme.typography.caption, { color: theme.colors.fgSecondary, marginBottom: 4 }]}>
                  {f.label}
                </Text>
                <TextInput
                  value={values[f.key] ?? ''}
                  onChangeText={(text) => setValues(prev => ({ ...prev, [f.key]: text }))}
                  placeholder={f.placeholder}
                  placeholderTextColor={theme.colors.fgSecondary}
                  keyboardType={f.keyboardType ?? 'default'}
                  multiline={f.multiline}
                  secureTextEntry={f.secureTextEntry}
                  style={commonStyles.input}
                />
              </View>
            ))}
          </ScrollView>

          <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>
    </Modal>
  );
}

const styles = StyleSheet.create({
  overlay: {
    flex: 1,
    justifyContent: 'flex-end',
  },
  sheet: {
    maxHeight: '80%',
    padding: 20,
    paddingBottom: 36,
  },
  header: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    alignItems: 'center',
    paddingBottom: 12,
    borderBottomWidth: 1,
    marginBottom: 12,
  },
  body: {
    maxHeight: 400,
  },
  field: {
    marginBottom: 12,
  },
  actions: {
    flexDirection: 'row',
    alignItems: 'center',
    gap: 8,
    marginTop: 8,
  },
});
