import React from 'react';
import {
  ApiOutlined,
  CheckCircleOutlined,
  CloseCircleOutlined,
  CloudServerOutlined,
  ReloadOutlined,
  RobotOutlined,
  SafetyOutlined,
  SaveOutlined,
  WarningOutlined,
} from '@ant-design/icons';
import {
  Alert,
  AutoComplete,
  Button,
  Card,
  Descriptions,
  Form,
  Input,
  InputNumber,
  Select,
  Space,
  Switch,
  Tag,
  Typography,
} from 'antd';
import type { AiProvider } from './helpers';
import {
  PROVIDER_OPTIONS,
  PROVIDER_DEFAULTS,
  formatDateTime,
  sourceColor,
  sourceLabel,
} from './helpers';
import styles from './index.module.css';

export interface AiConfigData {
  id: number;
  provider: AiProvider;
  baseUrl: string;
  hasApiKey: boolean;
  hasDatabaseKey: boolean;
  maskedApiKey: string | null;
  keySource: 'database' | 'environment' | 'none';
  defaultModel: string | null;
  enabled: boolean;
  supportsVision: boolean;
  timeoutMs: number;
  reasoningEffort: string | null;
  verified: boolean;
  lastTestedAt: string | null;
  lastTestLatencyMs: number | null;
  createdAt: string;
  updatedAt: string;
}

export interface TestResult {
  success: boolean;
  latencyMs: number | null;
  modelCount: number | null;
  modelAvailable: boolean;
  testedAt: string;
  message: string;
}

export interface FormValues {
  provider: AiProvider;
  baseUrl: string;
  apiKey: string;
  defaultModel: string;
  timeoutMs: number;
  supportsVision: boolean;
  reasoningEffort: string;
}

export const ProviderStep: React.FC<{
  canWrite: boolean;
  isFixedProvider: boolean;
  config?: AiConfigData | null;
  onProviderChange: (provider: AiProvider) => void;
}> = ({ canWrite, isFixedProvider, config, onProviderChange }) => {
  return (
    <Card title={<span className={styles.cardTitle}>服务商配置</span>} extra={<CloudServerOutlined />}>
      <Form.Item
        name="provider"
        label="Provider"
        rules={[{ required: true, message: '请选择 Provider' }]}
        preserve
      >
        <Select
          options={PROVIDER_OPTIONS}
          onChange={onProviderChange}
          disabled={!canWrite}
          size="large"
        />
      </Form.Item>

      <Form.Item
        name="baseUrl"
        label="Base URL"
        rules={[
          { required: true, message: '请输入 Base URL' },
          { type: 'url', message: '请输入合法的 URL' },
        ]}
        preserve
      >
        <Input
          placeholder={
            config?.provider ? PROVIDER_DEFAULTS[config.provider] : PROVIDER_DEFAULTS.DEEPSEEK
          }
          disabled={!canWrite || (isFixedProvider && canWrite)}
          size="large"
        />
      </Form.Item>

      <Form.Item
        name="timeoutMs"
        label="请求超时 (毫秒)"
        rules={[
          { required: true, message: '请输入超时时间' },
          { type: 'number', min: 1000, max: 120000, message: '范围: 1000-120000' },
        ]}
        preserve
      >
        <InputNumber
          min={1000}
          max={120000}
          step={1000}
          style={{ width: '100%' }}
          disabled={!canWrite}
          size="large"
        />
      </Form.Item>
    </Card>
  );
};

export const KeyStep: React.FC<{
  canWrite: boolean;
  config?: AiConfigData | null;
  onClearKey: () => void;
}> = ({ canWrite, config, onClearKey }) => {
  return (
    <Card title={<span className={styles.cardTitle}>密钥配置</span>} extra={<SafetyOutlined />}>
      <Form.Item name="apiKey" label="API Key" preserve>
        <Input.Password
          placeholder={config?.hasApiKey ? '已安全保存，留空则保持不变' : '请输入 API Key'}
          disabled={!canWrite}
          autoComplete="new-password"
          size="large"
        />
      </Form.Item>

      {config && (
        <Descriptions column={1} size="small" style={{ marginBottom: 12 }}>
          <Descriptions.Item label="状态">
            {config.hasApiKey ? (
              <Tag color="green">{config.maskedApiKey || '••••'}</Tag>
            ) : (
              <Tag color="default">未配置</Tag>
            )}
          </Descriptions.Item>
          <Descriptions.Item label="来源">
            <Tag color={sourceColor(config.keySource)}>{sourceLabel(config.keySource)}</Tag>
            {config.keySource === 'environment' && (
              <span style={{ marginLeft: 8, fontSize: 12, color: '#999' }}>
                由环境变量托管，需在服务器修改
              </span>
            )}
          </Descriptions.Item>
          <Descriptions.Item label="最后更新">{formatDateTime(config.updatedAt)}</Descriptions.Item>
        </Descriptions>
      )}

      {config?.hasDatabaseKey && canWrite && (
        <div style={{ marginBottom: 8 }}>
          <Button danger size="small" onClick={onClearKey}>
            清除服务器保存密钥
          </Button>
        </div>
      )}

      {config?.keySource === 'environment' && !config.hasDatabaseKey && (
        <div style={{ marginBottom: 8, fontSize: 12, color: '#999' }}>
          密钥由环境变量提供，无法通过页面清除
        </div>
      )}

      <div className={styles.safetyNote}>
        API Key 使用 AES-256-GCM 加密存储，每次保存使用随机 IV。传输层通过 HTTPS
        保护，服务端日志不记录密钥。
      </div>
      <div className={styles.safetyNoteKey}>
        也可通过环境变量 <Typography.Text code>AI_API_KEY</Typography.Text> 注入密钥，环境变量优先级高于数据库存储。
      </div>
    </Card>
  );
};

export const ModelStep: React.FC<{
  canWrite: boolean;
  config?: AiConfigData | null;
  onFetchModels: () => void;
  fetchingModels: boolean;
  modelOptions: Array<{ value: string; label: string }>;
}> = ({ canWrite, config, onFetchModels, fetchingModels, modelOptions }) => {
  return (
    <Card title={<span className={styles.cardTitle}>模型选择</span>} extra={<RobotOutlined />}>
      <div className={styles.modelFetchRow}>
        <Button
          icon={<ReloadOutlined />}
          onClick={onFetchModels}
          loading={fetchingModels}
          disabled={!canWrite}
        >
          获取模型列表
        </Button>
        {modelOptions.length > 0 && <Tag color="blue">{modelOptions.length} 个可用模型</Tag>}
      </div>

      <Form.Item
        name="defaultModel"
        label="默认模型"
        rules={[{ required: true, message: '请选择或输入默认模型' }]}
        style={{ marginTop: 16 }}
        preserve
      >
        <AutoComplete
          options={modelOptions}
          placeholder="选择或输入模型名称，如 deepseek-chat, gpt-4"
          disabled={!canWrite}
          size="large"
          filterOption={(inputValue, option) =>
            option?.value?.toLowerCase().includes(inputValue.toLowerCase()) ?? false
          }
        />
      </Form.Item>

      <Form.Item
        name="supportsVision"
        label="图片理解"
        valuePropName="checked"
        extra="仅当所选模型确实支持图片输入时开启；关闭时 AI 助手会阻止发送图片。"
        preserve
      >
        <Switch disabled={!canWrite} checkedChildren="已启用" unCheckedChildren="未启用" />
      </Form.Item>

      <Form.Item
        name="reasoningEffort"
        label="推理强度 (reasoning_effort)"
        extra="OpenAI o 系列等支持该参数的模型生效；DeepSeek 官方接口不支持，选择后也不会发送。"
        preserve
      >
        <Select
          disabled={!canWrite}
          size="large"
          options={[
            { value: '', label: '不设置（跟随模型默认）' },
            { value: 'low', label: '低 (low)' },
            { value: 'medium', label: '中 (medium)' },
            { value: 'high', label: '高 (high)' },
            { value: 'xhigh', label: '极高 (xhigh)' },
          ]}
        />
      </Form.Item>

      {config?.verified && (
        <div style={{ marginTop: 8 }}>
          <Tag icon={<CheckCircleOutlined />} color="success">
            上次验证通过
          </Tag>
          {config.lastTestLatencyMs != null && (
            <span style={{ marginLeft: 8, fontSize: 12, color: '#999' }}>
              延迟: {config.lastTestLatencyMs}ms
            </span>
          )}
        </div>
      )}
    </Card>
  );
};

export const TestResultCard: React.FC<{ testResult: TestResult | null }> = ({ testResult }) =>
  testResult ? (
    <Card size="small" className={styles.testResult}>
      <Descriptions column={{ xs: 1, sm: 2 }} size="small">
        <Descriptions.Item label="结果">
          {testResult.success ? (
            testResult.modelAvailable ? (
              <Tag icon={<CheckCircleOutlined />} color="success">
                成功
              </Tag>
            ) : (
              <Tag icon={<WarningOutlined />} color="warning">
                模型未找到
              </Tag>
            )
          ) : (
            <Tag icon={<CloseCircleOutlined />} color="error">
              失败
            </Tag>
          )}
        </Descriptions.Item>
        <Descriptions.Item label="延迟">
          {testResult.latencyMs != null ? `${testResult.latencyMs} ms` : '-'}
        </Descriptions.Item>
        <Descriptions.Item label="模型数量">
          {testResult.modelCount != null ? testResult.modelCount : '-'}
        </Descriptions.Item>
        <Descriptions.Item label="测试时间">{formatDateTime(testResult.testedAt)}</Descriptions.Item>
      </Descriptions>
      <Alert
        type={
          testResult.success
            ? testResult.modelAvailable
              ? 'success'
              : 'warning'
            : 'error'
        }
        title={testResult.message}
        style={{ marginTop: 8 }}
      />
    </Card>
  ) : null;

export const SaveTestStep: React.FC<{
  canWrite: boolean;
  canTest: boolean;
  config?: AiConfigData | null;
  currentProvider: AiProvider;
  formValues: FormValues;
  onSave: () => void;
  saving: boolean;
  onTest: () => void;
  testing: boolean;
  testResult: TestResult | null;
}> = ({
  canWrite,
  canTest,
  config,
  currentProvider,
  formValues,
  onSave,
  saving,
  onTest,
  testing,
  testResult,
}) => {
  const providerLabel =
    PROVIDER_OPTIONS.find((o) => o.value === currentProvider)?.label ?? currentProvider ?? '-';
  const hasFormKey = formValues.apiKey && formValues.apiKey !== '••••';
  return (
    <Card title={<span className={styles.cardTitle}>保存并测试</span>} extra={<CheckCircleOutlined />}>
      <Alert
        type="info"
        message="配置预览"
        description={
          <Descriptions column={1} size="small" style={{ marginTop: 8 }}>
            <Descriptions.Item label="服务商">
              <Tag color="blue">{providerLabel}</Tag>
            </Descriptions.Item>
            <Descriptions.Item label="Base URL">
              <Typography.Text code>{formValues.baseUrl || '-'}</Typography.Text>
            </Descriptions.Item>
            <Descriptions.Item label="默认模型">
              <Tag>{formValues.defaultModel || '未设置'}</Tag>
            </Descriptions.Item>
            <Descriptions.Item label="密钥">
              {config?.hasApiKey ? (
                <Tag color="green">{config.maskedApiKey || '••••'}</Tag>
              ) : hasFormKey ? (
                <Tag color="blue">已填写（未保存）</Tag>
              ) : (
                <Tag color="red">未配置</Tag>
              )}
            </Descriptions.Item>
            <Descriptions.Item label="超时">{formValues.timeoutMs}ms</Descriptions.Item>
            <Descriptions.Item label="图片理解">
              <Tag color={formValues.supportsVision ? 'blue' : 'default'}>
                {formValues.supportsVision ? '已启用' : '未启用'}
              </Tag>
            </Descriptions.Item>
            <Descriptions.Item label="状态">
              <Tag color={config?.enabled ? 'green' : 'default'}>
                {config?.enabled ? '已启用' : '未启用'}
              </Tag>
            </Descriptions.Item>
          </Descriptions>
        }
        style={{ marginBottom: 16 }}
      />
      <Space>
        {canWrite && (
          <Button
            type="primary"
            icon={<SaveOutlined />}
            onClick={onSave}
            loading={saving}
            size="large"
          >
            保存配置
          </Button>
        )}
        {canTest && (
          <Button icon={<ApiOutlined />} onClick={onTest} loading={testing} size="large">
            测试连接
          </Button>
        )}
      </Space>
      <TestResultCard testResult={testResult} />
    </Card>
  );
};
