import { redirect, type ActionFunctionArgs, type LoaderFunctionArgs, type MetaFunction } from "@remix-run/node";
import { Form, useActionData, useLoaderData, useNavigation } from "@remix-run/react";
import { useEffect, useState, useRef } from "react";
import { Button } from "~/components/ui/Button";
import { Card } from "~/components/ui/Card";
import { ENVIRONMENT_LABELS } from "./config-lists._index";
import { getConfigOptions, getConfigDetail, createConfig, updateConfig } from "~/api/system_setting/config-lists";
import configNewStyles from "~/styles/pages/config-lists_new.css?url";
import { toastService } from "~/components/ui/Toast";

export const links = () => [
  { rel: "stylesheet", href: configNewStyles }
];

export const handle = {
  breadcrumb: (data:LoaderData) => {
    return data.isEdit ? "编辑配置" : "新增配置";
  }
};

export const meta: MetaFunction = () => {
  return [
    { title: "新增配置 - 中国烟草AI合同及卷宗审核系统" },
    { name: "description", content: "新增或编辑系统配置项" },
    { name: "keywords", content: "配置管理,系统配置,新增配置,编辑配置" }
  ];
};

// 扩展环境枚举，添加"通用"选项
export enum ExtendedConfigEnvironment {
  DEV = 'dev',
  TEST = 'test',
  PROD = 'prod',
  COMMON = 'common'
}

// 扩展环境标签映射
export const EXTENDED_ENVIRONMENT_LABELS: Record<string, string> = {
  ...ENVIRONMENT_LABELS,
  [ExtendedConfigEnvironment.COMMON]: '通用'
};

// 新增配置表单数据
interface ConfigData {
  id: number;
  name: string;
  type: string;
  environment: string;
  is_active: boolean;
  config: Record<string, unknown>;
  remark?: string;
}

// 加载器数据类型
interface LoaderData {
  config?: ConfigData;
  isEdit: boolean;
  types: string[];
  environments: string[];
  error?: string;
}

// 新增配置表单数据
interface ActionData {
  success?: boolean;
  errors?: {
    name?: string;
    type?: string;
    environment?: string;
    config?: string;
    general?: string;
  };
  values?: Record<string, string>;
}

// 配置模板常量
const CONFIG_TEMPLATES = {
  database: {
    host: "localhost",
    port: 5432,
    database: "mydb",
    username: "admin",
    password: "******",
    pool: {
      min: 2,
      max: 10
    }
  },
  file: {
    storage: {
      type: "local", // or "s3", "oss"
      path: "/data/uploads",
      allowed_types: ["pdf", "docx", "jpg", "png"],
      max_size: 10485760, // 10MB
      backup_enabled: true
    }
  },
  ai: {
    ai_service: {
      provider: "openai",
      api_key: "sk-******",
      model: "gpt-4",
      max_tokens: 2000,
      temperature: 0.7,
      timeout: 30000,
      rate_limit: 10 // requests per minute
    }
  }
};


export async function loader({ request }: LoaderFunctionArgs) {
  const url = new URL(request.url);
  const id = url.searchParams.get("id");
  let config: ConfigData | undefined = undefined;
  
  try {
    // 获取配置选项
    const optionsResponse = await getConfigOptions();
    if (optionsResponse.error) {
      throw new Error(optionsResponse.error);
    }
    
    if (id) {
      // 获取配置详情
      const detailResponse = await getConfigDetail(id);
      if (detailResponse.error) {
        throw new Error(detailResponse.error);
      }
      config = detailResponse.data;
    }
    
    return Response.json({
      config,
      isEdit: !!config,
      types: optionsResponse.data?.types || [],
      environments: optionsResponse.data?.environments || [],
      error: undefined
    });
  } catch (error) {
    console.error("加载配置数据失败:", error);
    return Response.json({
      config: undefined,
      isEdit: false,
      types: [],
      environments: [],
      error: error instanceof Error ? error.message : "加载配置数据失败"
    });
  }
}


export async function action({ request }: ActionFunctionArgs) {
  const formData = await request.formData();
  const id = formData.get("id") as string;
  const name = formData.get("name") as string;
  const type = formData.get("type") as string;
  const environment = formData.get("environment") as string;
  const config = formData.get("config") as string;
  const is_active = formData.get("is_active") === "true";
  const remark = formData.get("remark") as string;
  
  const errors: ActionData["errors"] = {};
  
  // 表单验证
  if (!name || name.trim() === "") {
    errors.name = "配置名称不能为空";
  }else if(/^[a-zA-Z_]+$/.test(name)){
    errors.name = "配置名称只能包含英文字母和下划线";
  }
  
  if (!type) {
    errors.type = "请选择或输入所属模块";
  }
  
  if (!environment) {
    errors.environment = "请选择环境";
  }
  
  if (!config || config.trim() === "") {
    errors.config = "配置数据不能为空";
  } else {
    try {
      JSON.parse(config);
    } catch (e) {
      errors.config = "配置数据必须是有效的JSON格式";
    }
  }
  
  if (Object.keys(errors).length > 0) {
    return Response.json({
      errors,
      values: Object.fromEntries(formData) as Record<string, string>
    });
  }
  
  try {
    const configData = {
      name,
      type,
      environment,
      config: JSON.parse(config),
      is_active,
      remark
    };
    
    if (id) {
      // 更新配置
      const response = await updateConfig(id, configData);
      if (response.error) {
        throw new Error(response.error);
      }
    } else {
      // 创建配置
      const response = await createConfig(configData);
      if (response.error) {
        throw new Error(response.error);
      }
    }
    
    // 保存成功，显示成功提示并重定向
    toastService.success("保存成功");
    return redirect("/config-lists");
  } catch (error) {
    console.error("保存配置失败:", error);
    return Response.json({
      success: false,
      errors: {
        general: error instanceof Error ? error.message : "保存配置失败，请稍后重试"
      },
      values: Object.fromEntries(formData) as Record<string, string>
    });
  }
}


export default function ConfigNew() {
  const data = useLoaderData<typeof loader>();
  const actionData = useActionData<typeof action>();
  const navigation = useNavigation();
  const isSubmitting = navigation.state === "submitting";
  const formRef = useRef<HTMLFormElement>(null);
  
  const { config, isEdit, types, environments, error } = data;
  
  // 表单状态管理
  const [formValues, setFormValues] = useState<{
    name: string;
    type: string;
    environment: string;
    config: string;
    is_active: boolean;
    remark: string;
  }>({
    name: config?.name || "",
    type: config?.type || "",
    environment: config?.environment || "",
    config: config?.config ? JSON.stringify(config.config, null, 2) : "",
    is_active: config?.is_active ?? true,
    remark: config?.remark || "",
  });
  
  // 表单验证错误状态
  const [formErrors, setFormErrors] = useState<{
    name?: string;
    type?: string;
    environment?: string;
    config?: string;
    general?: string;
  }>({});
  
  // 字段是否被触摸过（用于确定何时显示错误）
  const [touchedFields, setTouchedFields] = useState<{
    name: boolean;
    type: boolean;
    environment: boolean;
    config: boolean;
  }>({
    name: false,
    type: false,
    environment: false,
    config: false
  });
  
  // 示例JSON状态
  const [exampleJsonValue, setExampleJsonValue] = useState("");
  const [selectedTemplate, setSelectedTemplate] = useState<keyof typeof CONFIG_TEMPLATES | null>(null);
  
  // 从 actionData 初始化表单错误
  useEffect(() => {
    if (actionData?.errors) {
      setFormErrors(actionData.errors);
    }
    
    // 如果提交后有错误，则将所有字段标记为已触摸
    if (actionData?.errors && Object.keys(actionData.errors).length > 0) {
      setTouchedFields({
        name: true,
        type: true,
        environment: true,
        config: true
      });
    }
  }, [actionData]);
  
  // 根据加载的配置数据初始化表单
  useEffect(() => {
    if (config) {
      setFormValues({
        name: config.name,
        type: config.type,
        environment: config.environment,
        config: JSON.stringify(config.config, null, 2),
        is_active: config.is_active,
        remark: config.remark || ""
      });
    }
    
    // 初始化示例JSON
    setExampleJsonValue(JSON.stringify({
      database: {
        host: "db.cluster.com",
        port: 5432,
        pool_size: 20,
        ssl: true
      },
      cache: {
        ttl: 3600,
        max_entries: 1000
      },
      feature_flags: ["new_ui", "analytics_v2"]
    }, null, 2));
  }, [config]);
  
  // 验证表单字段
  const validateField = (field: string, value: string): string => {
    switch (field) {
      case 'name':
        if(value.trim() === ""){
          return "配置名称不能为空";
        }else if(!/^[a-zA-Z_]+$/.test(value)){
          return "配置名称只能包含英文字母和下划线";
        }else if(value.length > 100){
          return "配置名称不能超过100个字符";
        }
        return "";
      case 'type':
        return value.trim() === "" ? "请选择所属模块" : "";
      case 'environment':
        return value.trim() === "" ? "请选择环境" : "";
      case 'config':
        if (value.trim() === "") {
          return "配置数据不能为空";
        } else {
          try {
            JSON.parse(value);
            return "";
          } catch (e) {
            return "配置数据必须是有效的JSON格式";
          }
        }
      default:
        return "";
    }
  };
  
  // 处理字段改变
  const handleInputChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
    const { name, value } = e.target;
    
    setFormValues(prev => ({
      ...prev,
      [name]: value
    }));
    
    // 标记字段为已触摸
    if (['name', 'type', 'environment', 'config'].includes(name)) {
      setTouchedFields(prev => ({
        ...prev,
        [name]: true
      }));
    }
    
    // 实时验证
    const error = validateField(name, value);
    setFormErrors(prev => ({
      ...prev,
      [name]: error
    }));
  };
  
  // 处理配置数据变更（JSON编辑器）
  const handleConfigDataChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
    const { value } = e.target;
    
    setFormValues(prev => ({
      ...prev,
      config: value
    }));
    
    // 标记字段为已触摸
    setTouchedFields(prev => ({
      ...prev,
      config: true
    }));
    
    // 实时验证
    const error = validateField('config', value);
    setFormErrors(prev => ({
      ...prev,
      config: error
    }));
  };
  
  // 格式化JSON
  const handleFormatJson = () => {
    if (formValues.config.trim() === "") return;
    
    try {
      const parsed = JSON.parse(formValues.config);
      const formatted = JSON.stringify(parsed, null, 2);
      
      setFormValues(prev => ({
        ...prev,
        config: formatted
      }));
      
      setFormErrors(prev => ({
        ...prev,
        config: ""
      }));
    } catch (error) {
      setFormErrors(prev => ({
        ...prev,
        config: `当前不是有效的JSON，无法格式化: ${error instanceof Error ? error.message : '未知错误'}`
      }));
    }
  };
  
  // 处理模块类型选择
  const handleModuleSelect = (moduleType: string) => {
    setFormValues(prev => ({
      ...prev,
      type: moduleType
    }));
    
    // 标记字段为已触摸
    setTouchedFields(prev => ({
      ...prev,
      type: true
    }));
    
    // 清除错误
    setFormErrors(prev => ({
      ...prev,
      type: ""
    }));
  };
  
  // 处理环境选择
  const handleEnvironmentSelect = (env: string) => {
    setFormValues(prev => ({
      ...prev,
      environment: env
    }));
    
    // 标记字段为已触摸
    setTouchedFields(prev => ({
      ...prev,
      environment: true
    }));
    
    // 清除错误
    setFormErrors(prev => ({
      ...prev,
      environment: ""
    }));
  };
  
  // 处理模板选择
  const handleTemplateSelect = (templateKey: keyof typeof CONFIG_TEMPLATES) => {
    setExampleJsonValue(JSON.stringify(CONFIG_TEMPLATES[templateKey], null, 2));
    setSelectedTemplate(templateKey);
  };
  
  // 处理启用状态变更
  const handleActiveChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    setFormValues(prev => ({
      ...prev,
      is_active: e.target.checked
    }));
  };
  
  // 提交前验证
  const handleBeforeSubmit = (e: React.FormEvent) => {
    // 标记所有字段为已触摸
    setTouchedFields({
      name: true,
      type: true,
      environment: true,
      config: true
    });
    
    // 验证所有字段
    const errors = {
      name: validateField('name', formValues.name),
      type: validateField('type', formValues.type),
      environment: validateField('environment', formValues.environment),
      config: validateField('config', formValues.config)
    };
    
    setFormErrors(errors);
    
    // 如果有错误，阻止提交
    if (errors.name || errors.type || errors.environment || errors.config) {
      e.preventDefault();
      
      // 滚动到第一个错误字段
      if (formRef.current) {
        const firstErrorField = Object.keys(errors).find(key => !!errors[key as keyof typeof errors]);
        if (firstErrorField) {
          const element = formRef.current.querySelector(`[name="${firstErrorField}"]`);
          if (element) {
            element.scrollIntoView({ behavior: 'smooth', block: 'center' });
          }
        }
      }
    }
  };
  
  // 如果加载数据时出错，显示错误信息
  if (error) {
    return (
      <div className="error-container p-6">
        <h1 className="text-xl font-bold text-red-500 mb-4">加载出错</h1>
        <p className="mb-4">{error}</p>
        <Button type="primary" to="/config-lists">返回列表</Button>
      </div>
    );
  }
  
  return (
    <div className="config-new-page">
      <div className="flex justify-between items-center mb-4">
        <span className="block text-xl font-medium">{isEdit ? "编辑系统配置" : "新增系统配置"}</span>
        <div className="form-actions">
          <Button type="default" to="/config-lists">
            <i className="ri-arrow-left-line mr-1"></i>
            返回
          </Button>
          <Button type="primary" disabled={isSubmitting} form="configForm">
            <i className="ri-save-line mr-1"></i>
            {isSubmitting ? '保存中...' : '保存'}
          </Button>
        </div>
      </div>

      {formErrors.general && (
        <div className="mb-4 w-full">
          <div className="error-message general-error">{formErrors.general}</div>
        </div>
      )}
      
      <Card className="config-form-card">
        <Form 
          method="post" 
          id="configForm" 
          className="config-form" 
          ref={formRef}
          onSubmit={handleBeforeSubmit}
        >
          {config?.id && <input type="hidden" name="id" value={config.id} />}
          
          {/* 配置名称和状态 */}
          <div className="form-row">
            <div className="form-group">
              <label htmlFor="name" className="form-label ">配置名称 <span className="text-red-500">*</span></label>
              <input
                type="text"
                id="name"
                name="name"
                className={`form-input ${touchedFields.name && formErrors.name ? 'input-error' : ''}`}
                value={formValues.name}
                onChange={handleInputChange}
                placeholder="请输入配置名称，如database_connection"
              />
              {touchedFields.name && formErrors.name && (
                <div className="error-message">{formErrors.name}</div>
              )}
              <div className="form-help">
                唯一标识符，配置名称应使用英文，推荐使用下划线命名方式
              </div>
            </div>
            
            <div className="form-group">
              <label htmlFor="is_active" className="form-label">状态</label>
              <div className="mt-2">
                <div className="flex items-center">
                  <input
                    type="checkbox"
                    id="is_active"
                    name="is_active"
                    value="true"
                    className="form-checkbox"
                    checked={formValues.is_active}
                    onChange={handleActiveChange}
                  />
                  <label htmlFor="is_active" className="form-checkbox-label">
                    启用此配置
                  </label>
                </div>
                <div className="form-help">
                  禁用配置后，系统将不会读取此配置
                </div>
              </div>
            </div>
          </div>
          
          {/* 所属模块 */}
          <div className="form-group">
            <label htmlFor="type" className="form-label">所属模块 <span className="text-red-500">*</span></label>
            <input
              type="hidden"
              name="type"
              value={formValues.type}
            />
            <input
              type="text"
              id="typeDisplay"
              className={`form-input ${touchedFields.type && formErrors.type ? 'input-error' : ''}`}
              value={formValues.type}
              onChange={handleInputChange}
              name="type"
              placeholder="请输入或选择所属模块"
              
            />
            {touchedFields.type && formErrors.type && (
              <div className="error-message">{formErrors.type}</div>
            )}
            <div className="tag-buttons mt-2">
              {types.map((type: string) => (
                <button
                  key={type}
                  type="button"
                  className={`tag-button ${formValues.type === type ? 'active' : ''}`}
                  onClick={() => handleModuleSelect(type)}
                >
                  {type}
                </button>
              ))}
            </div>
            <div className="form-help">
              将配置按功能模块进行分类，便于管理和查找
            </div>
          </div>
          
          {/* 环境 */}
          <div className="form-group">
            <label htmlFor="environment" className="form-label">环境 <span className="text-red-500">*</span></label>
            <input
              type="hidden"
              name="environment"
              value={formValues.environment}
            />
            <input
              type="text"
              id="environmentDisplay"
              className={`form-input ${touchedFields.environment && formErrors.environment ? 'input-error' : ''}`}
              value={formValues.environment}
              onChange={handleInputChange}
              name="environment"
              placeholder="请输入或选择环境"
            />
            {touchedFields.environment && formErrors.environment && (
              <div className="error-message">{formErrors.environment}</div>
            )}
            <div className="tag-buttons mt-2">
              {environments.map((env: string) => (
                <button
                  key={env}
                  type="button"
                  className={`tag-button ${formValues.environment === env ? 'active' : ''}`}
                  onClick={() => handleEnvironmentSelect(env)}
                >
                  {env}
                </button>
              ))}
            </div>
            <div className="form-help">
              不同环境可以使用相同的配置名称，系统会自动识别当前环境并使用对应配置
            </div>
          </div>
          
          {/* 配置数据 */}
          <div className="form-group">
            <label htmlFor="config" className="form-label ">配置数据 (JSON) <span className="text-red-500">*</span></label>
            <div className="grid grid-cols-1 md:grid-cols-2 gap-4" style={{ minHeight: '390px' }}>
              {/* 左侧JSON编辑区 */}
              <div className="h-full">
                <textarea
                  id="config"
                  name="config"
                  className={`json-editor ${touchedFields.config && formErrors.config ? 'input-error' : ''}`}
                  value={formValues.config}
                  onChange={handleConfigDataChange}
                  
                  placeholder='请输入JSON格式的配置数据'
                />
                <div className="editor-actions">
                  <Button 
                    type="default" 
                    size="small" 
                    onClick={(e) => {
                      e.preventDefault();
                      handleFormatJson();
                    }}
                  >
                    <i className="ri-braces-line mr-1"></i> 格式化JSON
                  </Button>
                </div>
                {touchedFields.config && formErrors.config && (
                  <div className="error-message">{formErrors.config}</div>
                )}
              </div>
              
              {/* 右侧示例区 */}
              <div className="h-full">
                <div className="example-card">
                  <div className="example-header">
                    <div className="example-title">配置示例</div>
                  </div>
                  <div className="example-content">
                    <div className="json-display">
                      {exampleJsonValue.split('\n').map((line, index) => (
                        <div key={index} className="json-line">
                          {line.split('').map((char, charIndex) => {
                            let className = 'json-char';
                            if (char === '{' || char === '}') className += ' json-brace';
                            if (char === '[' || char === ']') className += ' json-bracket';
                            if (char === '"') className += ' json-quote';
                            if (char === ':') className += ' json-colon';
                            if (char === ',') className += ' json-comma';
                            return (
                              <span key={charIndex} className={className}>
                                {char}
                              </span>
                            );
                          })}
                        </div>
                      ))}
                    </div>
                  </div>
                  <div className="example-footer">
                    <div className="text-sm font-medium mb-2">常用配置模板:</div>
                    <div className="flex flex-wrap gap-2">
                      <Button 
                        type="default"
                        size="small" 
                        className={`${selectedTemplate === 'database' ? 'border-[#00684a] text-[#00684a] focus:ring-0' : ''}`}
                        onClick={(e) => {
                          e.preventDefault();
                          handleTemplateSelect('database');
                        }}
                      >
                        数据库配置
                      </Button>
                      <Button 
                        type="default"
                        size="small" 
                        className={`${selectedTemplate === 'file' ? 'border-[#00684a] text-[#00684a] focus:ring-0' : ''}`}
                        onClick={(e) => {
                          e.preventDefault();
                          handleTemplateSelect('file');
                        }}
                      >
                        文件存储配置
                      </Button>
                      <Button 
                        type="default"
                        size="small" 
                        className={`${selectedTemplate === 'ai' ? 'border-[#00684a] text-[#00684a] focus:ring-0' : ''}`}
                        onClick={(e) => {
                          e.preventDefault();
                          handleTemplateSelect('ai');
                        }}
                      >
                        AI服务配置
                      </Button>
                    </div>
                  </div>
                </div>
              </div>
            </div>
            <div className="form-help">
              请输入JSON格式的配置数据，支持嵌套结构
            </div>
          </div>
          
          {/* 备注 */}
          <div className="form-group">
            <label htmlFor="remark" className="form-label">备注</label>
            <textarea
              id="remark"
              name="remark"
              className="form-textarea"
              value={formValues.remark}
              onChange={handleInputChange}
              rows={2}
              placeholder="请输入配置备注信息"
            />
            <div className="form-help">
              可选填项，用于描述配置的用途、注意事项等
            </div>
          </div>
          
          
        </Form>
      </Card>
    </div>
  );
}
