import { useState } from 'react';
import { useTranslation } from 'react-i18next';
import * as Dialog from '@radix-ui/react-dialog';
import { useCreateSpace, useUpdateSpace } from '../../hooks/useSpaces';
import type { Space } from '../../api';

interface SpaceFormDialogProps {
  /** 指定すると編集モード（名前・色・説明を更新）。未指定なら新規作成モード。 */
  space?: Space;
  onClose: () => void;
  onSaved?: (id: string) => void;
}

// DESIGN.md のブランド設定 UI に倣ったプリセット色。
const PRESET_COLORS = ['#3b82f6', '#8b5cf6', '#10b981', '#f59e0b', '#ef4444', '#64748b'];

/**
 * ワークスペースの新規作成・編集を兼ねるダイアログ。`space` を渡すと編集モードに
 * なり、名前・ブランド色・説明をまとめて更新する（種類は変更不可なので出さない）。
 */
export function SpaceFormDialog({ space, onClose, onSaved }: SpaceFormDialogProps) {
  const { t } = useTranslation('spaces');
  const isEdit = !!space;
  const createSpace = useCreateSpace();
  const updateSpace = useUpdateSpace();
  const [title, setTitle] = useState(space?.title ?? '');
  const [description, setDescription] = useState(space?.description ?? '');
  const [brandColor, setBrandColor] = useState<string>(space?.brandColor ?? PRESET_COLORS[0]);
  const [error, setError] = useState('');

  const submitting = createSpace.isPending || updateSpace.isPending;

  const handleSubmit = async () => {
    const trimmed = title.trim();
    if (!trimmed) {
      setError(t('formDialog.error.nameRequired'));
      return;
    }
    setError('');
    try {
      if (isEdit) {
        const updated = await updateSpace.mutateAsync({
          id: space!.id,
          patch: { title: trimmed, description: description.trim(), brandColor: brandColor || null },
        });
        onSaved?.(updated.id);
      } else {
        const created = await createSpace.mutateAsync({
          title: trimmed,
          description: description.trim() || undefined,
          brandColor: brandColor || null,
        });
        onSaved?.(created.id);
      }
      onClose();
    } catch (e) {
      setError(e instanceof Error ? e.message : isEdit ? t('formDialog.error.updateFailed') : t('formDialog.error.createFailed'));
    }
  };

  return (
    <Dialog.Root open onOpenChange={(open) => { if (!open) onClose(); }}>
      <Dialog.Portal>
        <Dialog.Overlay className="fixed inset-0 bg-slate-900/50 z-30" />
        <Dialog.Content
          className="fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 bg-surface rounded-2xl shadow-2xl w-full overflow-auto z-40 focus:outline-none"
          style={{ maxWidth: 'min(480px, 92vw)', maxHeight: '88dvh' }}
        >
          <div className="p-5">
            <div className="flex items-start justify-between gap-3 mb-5">
              <div>
                <Dialog.Title className="text-xl font-extrabold text-slate-900 m-0">
                  {isEdit ? t('formDialog.title.edit') : t('formDialog.title.create')}
                </Dialog.Title>
                <Dialog.Description className="mt-1 text-[13px] text-slate-500">
                  {isEdit
                    ? t('formDialog.description.edit')
                    : t('formDialog.description.create')}
                </Dialog.Description>
              </div>
              <Dialog.Close asChild>
                <button
                  aria-label={t('formDialog.close')}
                  className="p-1.5 rounded-lg text-slate-400 hover:text-slate-600 hover:bg-slate-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent-ring"
                >
                  <svg className="w-4 h-4" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
                    <path d="M4 4l8 8M12 4l-8 8" />
                  </svg>
                </button>
              </Dialog.Close>
            </div>

            <div className="flex flex-col gap-4">
              <label className="flex flex-col gap-1">
                <span className="text-xs font-semibold text-slate-600">{t('formDialog.field.name')}<span className="text-red-500"> *</span></span>
                <input
                  autoFocus
                  data-testid="space-title-input"
                  value={title}
                  onChange={e => setTitle(e.target.value)}
                  placeholder={t('formDialog.field.namePlaceholder')}
                  className="rounded-md border border-hairline bg-canvas px-3 py-2 text-sm text-slate-800 focus:outline-none focus:ring-2 focus:ring-accent-ring"
                />
              </label>

              <label className="flex flex-col gap-1">
                <span className="text-xs font-semibold text-slate-600">{t('formDialog.field.description')}</span>
                <textarea
                  data-testid="space-description-input"
                  value={description}
                  onChange={e => setDescription(e.target.value)}
                  rows={2}
                  placeholder={t('formDialog.field.descriptionPlaceholder')}
                  className="resize-none rounded-md border border-hairline bg-canvas px-3 py-2 text-sm text-slate-800 focus:outline-none focus:ring-2 focus:ring-accent-ring"
                />
              </label>

              <div className="flex flex-col gap-1.5">
                <span className="text-xs font-semibold text-slate-600">{t('formDialog.field.brandColor')}</span>
                <div className="flex items-center gap-2">
                  {PRESET_COLORS.map(c => (
                    <button
                      key={c}
                      type="button"
                      onClick={() => setBrandColor(c)}
                      aria-label={t('formDialog.colorSwatch', { color: c })}
                      className={`h-6 w-6 rounded-full transition-transform ${
                        brandColor === c ? 'ring-2 ring-offset-2 ring-[var(--brand-primary)]' : ''
                      }`}
                      style={{ background: c }}
                    />
                  ))}
                  <label className="ml-1 flex cursor-pointer items-center" title={t('formDialog.customColor')}>
                    <input
                      type="color"
                      value={brandColor}
                      onChange={e => setBrandColor(e.target.value)}
                      className="h-6 w-6 cursor-pointer rounded-md border border-hairline bg-none p-0"
                    />
                  </label>
                </div>
              </div>

              {error && <p className="text-sm text-red-600">{error}</p>}

              <div className="mt-1 flex justify-end gap-2">
                <Dialog.Close asChild>
                  <button
                    type="button"
                    className="rounded-md border border-hairline px-4 py-2 text-sm font-semibold text-slate-700 transition-colors hover:bg-surface-2"
                  >
                    {t('common:cancel')}
                  </button>
                </Dialog.Close>
                <button
                  type="button"
                  data-testid="space-form-submit"
                  onClick={handleSubmit}
                  disabled={submitting}
                  className="rounded-md bg-accent px-4 py-2 text-sm font-bold text-accent-fg transition-colors hover:opacity-90 disabled:opacity-50"
                >
                  {submitting ? (isEdit ? t('formDialog.saving') : t('formDialog.creating')) : (isEdit ? t('common:save') : t('formDialog.createButton'))}
                </button>
              </div>
            </div>
          </div>
        </Dialog.Content>
      </Dialog.Portal>
    </Dialog.Root>
  );
}
