/*
Copyright (C) 2025 QuantumNous

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.

For commercial licensing, please contact support@quantumnous.com
*/

import React from 'react';
import {
  Card,
  Select,
  Typography,
  Button,
  Switch,
  RadioGroup,
  Input,
  Slider,
} from '@douyinfe/semi-ui';
import { Sparkles, Users, ToggleLeft, X, Settings } from 'lucide-react';
import { useTranslation } from 'react-i18next';
import { formatVideoResolutionDisplayLabel, renderGroupOption, selectFilter } from '../../helpers';
import {
  PLAYGROUND_IMAGE_SIZE_OPTIONS,
  PLAYGROUND_VIDEO_DURATION_OPTIONS,
} from '../../constants/playground.constants';
import ParameterControl from './ParameterControl';

/**
 * 操练场分组下拉：与全局 renderGroupOption 一致，但不展示倍率角标。
 * @param {Record<string, unknown>} item Semi Select 传入的选项渲染参数
 */
const renderPlaygroundGroupOption = (item) =>
  renderGroupOption({ ...item, ratio: undefined });
import ImageUrlInput from './ImageUrlInput';
import VideoUrlInput from './VideoUrlInput';
import ConfigManager from './ConfigManager';
import CustomRequestEditor from './CustomRequestEditor';

const SettingsPanel = ({
  inputs,
  parameterEnabled,
  models,
  modelTypes,
  supplierOptions,
  groups,
  styleState,
  showDebugPanel,
  customRequestMode,
  customRequestBody,
  onInputChange,
  onParameterToggle,
  onCloseSettings,
  onConfigImport,
  onConfigReset,
  onCustomRequestModeChange,
  onCustomRequestBodyChange,
  previewPayload,
  messages,
  userId,
}) => {
  const { t } = useTranslation();

  const currentConfig = {
    inputs,
    parameterEnabled,
    showDebugPanel,
    customRequestMode,
    customRequestBody,
  };
  const displayMode = inputs.display_mode || 'text';
  const isImageMode = displayMode === 'image';
  const isVideoMode = displayMode === 'video';
  const mediaModeEnabled = isImageMode || isVideoMode;
  const videoMediaHint = isVideoMode
    ? t(
        '操练场视频素材提示',
        '图片地址：第 1 张为首帧，2 张为首尾帧，更多张时最后一张为尾帧。视频地址：填写则作为源视频参与生成。未填写的字段不会加入请求。',
      )
    : '';
  const applyVideoResolutionPreset = (preset) => {
    const [w, h] = String(preset || '1280x720')
      .split('x')
      .map((n) => Number(n));
    onInputChange('video_resolution_preset', preset);
    if (Number.isFinite(w) && Number.isFinite(h)) {
      onInputChange('video_width', w);
      onInputChange('video_height', h);
    }
  };

  return (
    <Card
      className='h-full flex flex-col'
      bordered={false}
      bodyStyle={{
        padding: styleState.isMobile ? '16px' : '24px',
        height: '100%',
        display: 'flex',
        flexDirection: 'column',
      }}
    >
      {/* 标题区域 - 与调试面板保持一致 */}
      <div className='flex items-center justify-between mb-6 flex-shrink-0'>
        <div className='flex items-center'>
          <div className='w-10 h-10 rounded-full bg-gradient-to-r from-purple-500 to-pink-500 flex items-center justify-center mr-3'>
            <Settings size={20} className='text-white' />
          </div>
          <Typography.Title heading={5} className='mb-0'>
            {t('模型配置')}
          </Typography.Title>
        </div>

        {styleState.isMobile && onCloseSettings && (
          <Button
            icon={<X size={16} />}
            onClick={onCloseSettings}
            theme='borderless'
            type='tertiary'
            size='small'
            className='!rounded-lg'
          />
        )}
      </div>

      {/* 展示模式（置顶，左右切换） */}
      <div className='mb-4 flex-shrink-0'>
        <Typography.Text strong className='text-sm mb-2 block'>
          {t('展示模式')}
        </Typography.Text>
        <RadioGroup
          type='button'
          buttonSize='large'
          value={displayMode}
          options={[
            { label: t('文本'), value: 'text' },
            { label: t('图片'), value: 'image' },
            { label: t('视频'), value: 'video' },
          ]}
          onChange={(e) => {
            const nextMode = e?.target?.value || 'text';
            onInputChange('display_mode', nextMode);
            // 切换模式时重置类型筛选，避免残留筛选导致“明明有模型却不显示”
            onInputChange('model_type', '');
          }}
          disabled={customRequestMode}
        />
      </div>

      {/* 移动端配置管理 */}
      {styleState.isMobile && (
        <div className='mb-4 flex-shrink-0'>
          <ConfigManager
            currentConfig={currentConfig}
            onConfigImport={onConfigImport}
            onConfigReset={onConfigReset}
            styleState={{ ...styleState, isMobile: false }}
            messages={messages}
            userId={userId}
          />
        </div>
      )}

      <div className='space-y-6 overflow-y-auto flex-1 pr-2 model-settings-scroll'>
        {/* 自定义请求体编辑器 */}
        <CustomRequestEditor
          customRequestMode={customRequestMode}
          customRequestBody={customRequestBody}
          onCustomRequestModeChange={onCustomRequestModeChange}
          onCustomRequestBodyChange={onCustomRequestBodyChange}
          defaultPayload={previewPayload}
        />

        {/* 分组选择 */}
        <div className={customRequestMode ? 'opacity-50' : ''}>
          <div className='flex items-center gap-2 mb-2'>
            <Users size={16} className='text-gray-500' />
            <Typography.Text strong className='text-sm'>
              {t('分组')}
            </Typography.Text>
            {customRequestMode && (
              <Typography.Text className='text-xs text-orange-600'>
                ({t('已在自定义模式中忽略')})
              </Typography.Text>
            )}
          </div>
          <Select
            placeholder={t('请选择分组')}
            name='group'
            required
            selection
            filter={selectFilter}
            autoClearSearchValue={false}
            onChange={(value) => onInputChange('group', value)}
            value={inputs.group}
            autoComplete='new-password'
            optionList={groups}
            renderOptionItem={renderPlaygroundGroupOption}
            style={{ width: '100%' }}
            dropdownStyle={{ width: '100%', maxWidth: '100%' }}
            className='!rounded-lg'
            disabled={customRequestMode}
          />
        </div>

        {/* 模型选择 */}
        <div className={customRequestMode ? 'opacity-50' : ''}>
          <div className='flex items-center gap-2 mb-2'>
            <Sparkles size={16} className='text-gray-500' />
            <Typography.Text strong className='text-sm'>
              {t('模型类型')}
            </Typography.Text>
            {customRequestMode && (
              <Typography.Text className='text-xs text-orange-600'>
                ({t('已在自定义模式中忽略')})
              </Typography.Text>
            )}
          </div>
          {/* model_type 为 0 表示未关联类型，与空字符串「全部」不同，不能用 value={x || ''} */}
          <Select
            placeholder={t('请选择模型类型')}
            name='model_type'
            selection
            filter={selectFilter}
            autoClearSearchValue={false}
            onChange={(value) =>
              onInputChange(
                'model_type',
                value === undefined || value === null ? '' : value,
              )
            }
            value={
              inputs.model_type === undefined || inputs.model_type === null
                ? ''
                : inputs.model_type
            }
            autoComplete='new-password'
            optionList={modelTypes}
            style={{ width: '100%' }}
            dropdownStyle={{ width: '100%', maxWidth: '100%' }}
            className='!rounded-lg mb-3'
            disabled={customRequestMode}
          />

          <div className='flex items-center gap-2 mb-2'>
            <Sparkles size={16} className='text-gray-500' />
            <Typography.Text strong className='text-sm'>
              {t('模型')}
            </Typography.Text>
            {customRequestMode && (
              <Typography.Text className='text-xs text-orange-600'>
                ({t('已在自定义模式中忽略')})
              </Typography.Text>
            )}
          </div>
          <Select
            placeholder={t('请选择模型')}
            name='model'
            required
            selection
            filter={selectFilter}
            autoClearSearchValue={false}
            onChange={(value) => onInputChange('model', value)}
            value={inputs.model}
            autoComplete='new-password'
            optionList={models}
            style={{ width: '100%' }}
            dropdownStyle={{ width: '100%', maxWidth: '100%' }}
            className='!rounded-lg'
            disabled={customRequestMode}
          />

          <div className='flex items-center gap-2 mb-2 mt-3'>
            <Sparkles size={16} className='text-gray-500' />
            <Typography.Text strong className='text-sm'>
              {t('渠道商')}
            </Typography.Text>
            {customRequestMode && (
              <Typography.Text className='text-xs text-orange-600'>
                ({t('已在自定义模式中忽略')})
              </Typography.Text>
            )}
          </div>
          <Select
            placeholder={t('请选择渠道商')}
            name='selected_route_slug'
            selection
            filter={selectFilter}
            autoClearSearchValue={false}
            onChange={(value) =>
              onInputChange(
                'selected_route_slug',
                value === undefined || value === null ? '' : value,
              )
            }
            value={
              inputs.selected_route_slug === undefined ||
              inputs.selected_route_slug === null
                ? ''
                : inputs.selected_route_slug
            }
            autoComplete='new-password'
            optionList={supplierOptions}
            style={{ width: '100%' }}
            dropdownStyle={{ width: '100%', maxWidth: '100%' }}
            className='!rounded-lg'
            disabled={customRequestMode}
          />

        </div>

        {/* 素材 URL：视频模式分图片地址 / 视频地址 */}
        {mediaModeEnabled && (
          <div className={customRequestMode ? 'opacity-50' : ''}>
            <ImageUrlInput
              imageUrls={inputs.imageUrls}
              imageEnabled={true}
              onImageUrlsChange={(urls) => onInputChange('imageUrls', urls)}
              onImageEnabledChange={() => {}}
              allowToggle={false}
              disabled={customRequestMode}
            />
            {isVideoMode && (
              <VideoUrlInput
                videoUrls={inputs.videoUrls || ['']}
                videoEnabled={true}
                onVideoUrlsChange={(urls) => onInputChange('videoUrls', urls)}
                onVideoEnabledChange={() => {}}
                allowToggle={false}
                disabled={customRequestMode}
              />
            )}
            <Typography.Text className='text-xs mt-1 block text-gray-500'>
              {isVideoMode
                ? videoMediaHint
                : t('图片模式支持图片 URL 作为素材')}
            </Typography.Text>
          </div>
        )}

        {/* 模式参数区 */}
        {displayMode === 'text' && (
          <div className={customRequestMode ? 'opacity-50' : ''}>
            <ParameterControl
              inputs={inputs}
              parameterEnabled={parameterEnabled}
              onInputChange={onInputChange}
              onParameterToggle={onParameterToggle}
              disabled={customRequestMode}
            />
          </div>
        )}

        {isImageMode && (
          <div className={customRequestMode ? 'opacity-50' : ''}>
            <Typography.Text strong className='text-sm mb-2 block'>
              {t('图片参数')}
            </Typography.Text>
            <Typography.Text className='text-xs text-gray-500 mb-2 block'>
              {t('用于文生图/图生图的核心参数')}
            </Typography.Text>
            <Typography.Text className='text-xs text-orange-600 mb-2 block'>
              {t('计费以实际图片质量为准')}
            </Typography.Text>
            <div className='space-y-3'>
              <Typography.Text strong className='text-sm block'>
                {t('分辨率')}
              </Typography.Text>
              <Select
                placeholder={t('图片尺寸')}
                optionList={PLAYGROUND_IMAGE_SIZE_OPTIONS}
                value={inputs.image_size}
                onChange={(value) => onInputChange('image_size', value)}
                disabled={customRequestMode}
                style={{ width: '100%' }}
                renderSelectedItem={(option) => (
                  <span>
                    {option?.label ??
                      formatVideoResolutionDisplayLabel(inputs.image_size) ??
                      inputs.image_size}
                  </span>
                )}
              />
              <Typography.Text strong className='text-sm block'>
                {t('生成图片数量')}
              </Typography.Text>
              <Input
                type='number'
                min={1}
                max={4}
                placeholder={t('生成数量 n')}
                value={inputs.image_n}
                onChange={(value) =>
                  onInputChange('image_n', Math.max(1, Math.min(4, Number(value) || 1)))
                }
                disabled={customRequestMode}
              />
            </div>
          </div>
        )}

        {isVideoMode && (
          <div className={customRequestMode ? 'opacity-50' : ''}>
            <Typography.Text strong className='text-sm mb-2 block'>
              {t('视频参数')}
            </Typography.Text>
            <Typography.Text className='text-xs text-gray-500 mb-2 block'>
              {t('用于视频生成的核心参数（时长、分辨率）')}
            </Typography.Text>
            <Typography.Text className='text-xs text-orange-600 mb-2 block'>
              {t('计费以实际视频质量为准')}
            </Typography.Text>
            <div className='space-y-3'>
              <Typography.Text strong className='text-sm block'>
                {t('视频时长（秒）')}
              </Typography.Text>
              <Select
                optionList={PLAYGROUND_VIDEO_DURATION_OPTIONS}
                value={Math.max(
                  3,
                  Math.min(30, Number(inputs.video_duration) || 5),
                )}
                onChange={(value) =>
                  onInputChange('video_duration', Number(value) || 5)
                }
                disabled={customRequestMode}
                style={{ width: '100%' }}
              />
              <Typography.Text strong className='text-sm block'>
                {t('分辨率')}
              </Typography.Text>
              <Select
                placeholder={t('分辨率预设')}
                optionList={[
                  { label: '960x540', value: '960x540' },
                  { label: '1280x720', value: '1280x720' },
                  { label: '1920x1080', value: '1920x1080' },
                ]}
                value={inputs.video_resolution_preset}
                onChange={(value) => applyVideoResolutionPreset(value)}
                disabled={customRequestMode}
                style={{ width: '100%' }}
              />
              <div className='grid grid-cols-2 gap-2'>
                <Input
                  type='number'
                  min={320}
                  max={4096}
                  placeholder={t('宽度 width')}
                  value={inputs.video_width}
                  onChange={(value) => onInputChange('video_width', Number(value) || 1280)}
                  disabled={customRequestMode}
                />
                <Input
                  type='number'
                  min={320}
                  max={4096}
                  placeholder={t('高度 height')}
                  value={inputs.video_height}
                  onChange={(value) => onInputChange('video_height', Number(value) || 720)}
                  disabled={customRequestMode}
                />
              </div>
              <Typography.Text strong className='text-sm block'>
                {t('运动强度 motion')}
              </Typography.Text>
              <div className='px-1'>
                <Slider
                  min={0}
                  max={1}
                  step={0.1}
                  marks={{
                    0: '0.0',
                    0.5: '0.5',
                    1: '1.0',
                  }}
                  value={Number(inputs.video_motion ?? 0.4)}
                  onChange={(value) =>
                    onInputChange('video_motion', Number(value ?? 0.4))
                  }
                  disabled={customRequestMode}
                  tipFormatter={(value) => `${Number(value).toFixed(1)}`}
                />
              </div>
              <Typography.Text strong className='text-sm block'>
                {t('生成数量 n')}
              </Typography.Text>
              <Select
                optionList={[
                  { label: '1', value: 1 },
                  { label: '2', value: 2 },
                  { label: '3', value: 3 },
                ]}
                value={Math.max(1, Math.min(3, Number(inputs.video_n) || 1))}
                onChange={(value) =>
                  onInputChange('video_n', Math.max(1, Math.min(3, Number(value) || 1)))
                }
                disabled={customRequestMode}
                style={{ width: '100%' }}
              />
            </div>
          </div>
        )}

        {/* 流式输出开关 */}
        <div className={customRequestMode ? 'opacity-50' : ''}>
          <div className='flex items-center justify-between'>
            <div className='flex items-center gap-2'>
              <ToggleLeft size={16} className='text-gray-500' />
              <Typography.Text strong className='text-sm'>
                {t('流式输出')}
              </Typography.Text>
              {customRequestMode && (
                <Typography.Text className='text-xs text-orange-600'>
                  ({t('已在自定义模式中忽略')})
                </Typography.Text>
              )}
            </div>
            <Switch
              checked={inputs.stream}
              onChange={(checked) => onInputChange('stream', checked)}
              checkedText={t('开')}
              uncheckedText={t('关')}
              size='small'
              disabled={customRequestMode || isImageMode || isVideoMode}
            />
          </div>
          {(isImageMode || isVideoMode) && (
            <Typography.Text className='text-xs text-orange-600'>
              {t('图片/视频模式不支持流式输出，已自动关闭')}
            </Typography.Text>
          )}
        </div>
      </div>

      {/* 桌面端的配置管理放在底部 */}
      {!styleState.isMobile && (
        <div className='flex-shrink-0 pt-3'>
          <ConfigManager
            currentConfig={currentConfig}
            onConfigImport={onConfigImport}
            onConfigReset={onConfigReset}
            styleState={styleState}
            messages={messages}
            userId={userId}
          />
        </div>
      )}
    </Card>
  );
};

export default SettingsPanel;
