import {RefreshCcw, Save} from 'lucide-react';
import {FormEvent, useEffect, useState} from 'react';

import {
  getAdminCreationEntryConfig,
  upsertAdminCreationEntryConfig,
} from '../api/adminApiClient';
import type {
  AdminCreationEntryTypeConfigPayload,
  UnifiedCreationFieldPayload,
  UnifiedCreationSpecPayload,
} from '../api/adminApiTypes';
import {useAdminWriteConfirm} from '../components/useAdminWriteConfirm';
import {handlePageError} from './pageUtils';

interface AdminCreationEntrySwitchPageProps {
  token: string;
  onUnauthorized: (message?: string) => void;
}

export function AdminCreationEntrySwitchPage({
  token,
  onUnauthorized,
}: AdminCreationEntrySwitchPageProps) {
  const [entries, setEntries] = useState<AdminCreationEntryTypeConfigPayload[]>([]);
  const [selectedId, setSelectedId] = useState('puzzle');
  const [title, setTitle] = useState('');
  const [subtitle, setSubtitle] = useState('');
  const [badge, setBadge] = useState('');
  const [imageSrc, setImageSrc] = useState('');
  const [visible, setVisible] = useState(true);
  const [open, setOpen] = useState(true);
  const [sortOrder, setSortOrder] = useState('30');
  const [categoryId, setCategoryId] = useState('recent');
  const [categoryLabel, setCategoryLabel] = useState('最近创作');
  const [categorySortOrder, setCategorySortOrder] = useState('10');
  const [unifiedCreationSpecJson, setUnifiedCreationSpecJson] = useState('');
  const [isLoading, setIsLoading] = useState(false);
  const [isSaving, setIsSaving] = useState(false);
  const [listErrorMessage, setListErrorMessage] = useState('');
  const [errorMessage, setErrorMessage] = useState('');
  const {confirmWrite, confirmDialog} = useAdminWriteConfirm();

  useEffect(() => {
    void refreshEntries();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [token]);

  async function refreshEntries() {
    setIsLoading(true);
    setListErrorMessage('');
    try {
      const response = await getAdminCreationEntryConfig(token);
      const nextEntries = sortEntries(response.entries);
      setEntries(nextEntries);
      fillForm(
        nextEntries.find((entry) => entry.id === selectedId) ?? nextEntries[0] ?? null,
      );
    } catch (error: unknown) {
      handlePageError(error, onUnauthorized, setListErrorMessage);
    } finally {
      setIsLoading(false);
    }
  }

  async function handleSave(event: FormEvent<HTMLFormElement>) {
    event.preventDefault();
    if (isSaving) {
      return;
    }

    const targetId = selectedId.trim();
    setErrorMessage('');
    const unifiedCreationSpecResult = parseUnifiedCreationSpecJson(
      targetId,
      unifiedCreationSpecJson,
    );
    if (!unifiedCreationSpecResult.ok) {
      setErrorMessage(unifiedCreationSpecResult.message);
      return;
    }
    const confirmed = await confirmWrite({
      action: '保存创作入口开关',
      target: targetId,
    });
    if (!confirmed) {
      return;
    }

    setIsSaving(true);
    try {
      const response = await upsertAdminCreationEntryConfig(token, {
        id: targetId,
        title: title.trim(),
        subtitle: subtitle.trim(),
        badge: badge.trim(),
        imageSrc: imageSrc.trim(),
        visible,
        open,
        sortOrder: parseInteger(sortOrder),
        categoryId: categoryId.trim(),
        categoryLabel: categoryLabel.trim(),
        categorySortOrder: parseInteger(categorySortOrder),
        unifiedCreationSpec: unifiedCreationSpecResult.spec,
      });
      const nextEntries = sortEntries(response.entries);
      setEntries(nextEntries);
      fillForm(nextEntries.find((entry) => entry.id === targetId) ?? null);
    } catch (error: unknown) {
      handlePageError(error, onUnauthorized, setErrorMessage);
    } finally {
      setIsSaving(false);
    }
  }

  function fillForm(entry: AdminCreationEntryTypeConfigPayload | null) {
    if (!entry) {
      return;
    }
    setSelectedId(entry.id);
    setTitle(entry.title);
    setSubtitle(entry.subtitle);
    setBadge(entry.badge);
    setImageSrc(entry.imageSrc);
    setVisible(entry.visible);
    setOpen(entry.open);
    setSortOrder(String(entry.sortOrder));
    setCategoryId(entry.categoryId);
    setCategoryLabel(entry.categoryLabel);
    setCategorySortOrder(String(entry.categorySortOrder));
    setUnifiedCreationSpecJson(formatUnifiedCreationSpecJson(entry.unifiedCreationSpec));
  }

  return (
    <section className="admin-page">
      <div className="admin-page-heading">
        <div>
          <h2>创作入口开关</h2>
          <p>控制创作中心入口展示与运行态路由可用性</p>
        </div>
        <button
          className="admin-secondary-button"
          disabled={isLoading}
          type="button"
          onClick={refreshEntries}
        >
          <RefreshCcw size={17} aria-hidden="true" />
          <span>{isLoading ? '刷新中' : '刷新'}</span>
        </button>
      </div>

      {listErrorMessage ? (
        <div className="admin-alert" role="status">
          {listErrorMessage}
        </div>
      ) : null}

      <div className="admin-two-column admin-two-column-wide">
        <form className="admin-panel admin-form" onSubmit={handleSave}>
          <div className="admin-form-row">
            <label className="admin-field admin-field-fill">
              <span>入口 ID</span>
              <input
                value={selectedId}
                onChange={(event) => setSelectedId(event.target.value)}
              />
            </label>
            <label className="admin-switch-field">
              <input
                checked={visible}
                type="checkbox"
                onChange={(event) => setVisible(event.target.checked)}
              />
              <span>展示</span>
            </label>
            <label className="admin-switch-field">
              <input
                checked={open}
                type="checkbox"
                onChange={(event) => setOpen(event.target.checked)}
              />
              <span>开放</span>
            </label>
          </div>

          <div className="admin-form-row">
            <label className="admin-field">
              <span>标题</span>
              <input value={title} onChange={(event) => setTitle(event.target.value)} />
            </label>
            <label className="admin-field">
              <span>角标</span>
              <input value={badge} onChange={(event) => setBadge(event.target.value)} />
            </label>
          </div>

          <label className="admin-field">
            <span>副标题</span>
            <input value={subtitle} onChange={(event) => setSubtitle(event.target.value)} />
          </label>

          <label className="admin-field">
            <span>图片路径</span>
            <input value={imageSrc} onChange={(event) => setImageSrc(event.target.value)} />
          </label>

          <label className="admin-field">
            <span>排序</span>
            <input
              inputMode="numeric"
              value={sortOrder}
              onChange={(event) => setSortOrder(event.target.value)}
            />
          </label>

          <div className="admin-form-row">
            <label className="admin-field">
              <span>分类 ID</span>
              <input
                value={categoryId}
                onChange={(event) => setCategoryId(event.target.value)}
              />
            </label>
            <label className="admin-field">
              <span>分类名称</span>
              <input
                value={categoryLabel}
                onChange={(event) => setCategoryLabel(event.target.value)}
              />
            </label>
          </div>

          <label className="admin-field">
            <span>分类排序</span>
            <input
              inputMode="numeric"
              value={categorySortOrder}
              onChange={(event) => setCategorySortOrder(event.target.value)}
            />
          </label>

          <section className="admin-subsection">
            <div className="admin-subsection-heading">
              <span>统一创作契约</span>
              <span>{unifiedCreationSpecJson.trim() ? '已配置' : '未配置'}</span>
            </div>
            {unifiedCreationSpecJson.trim() ? (
              <UnifiedCreationSpecSummary specJson={unifiedCreationSpecJson} />
            ) : (
              <div className="admin-muted-text">未配置统一创作页契约</div>
            )}
            <label className="admin-field">
              <span>契约 JSON</span>
              <textarea
                rows={12}
                value={unifiedCreationSpecJson}
                onChange={(event) => setUnifiedCreationSpecJson(event.target.value)}
              />
            </label>
          </section>

          {errorMessage ? (
            <div className="admin-alert" role="status">
              {errorMessage}
            </div>
          ) : null}

          <div className="admin-form-actions">
            <button className="admin-primary-button" disabled={isSaving} type="submit">
              <Save size={17} aria-hidden="true" />
              <span>{isSaving ? '保存中' : '保存入库'}</span>
            </button>
          </div>
        </form>

        <section className="admin-panel">
          <div className="admin-table-wrap">
            <table className="admin-table admin-table-compact">
              <thead>
                <tr>
                  <th>入口</th>
                  <th>展示</th>
                  <th>开放</th>
                  <th>统一契约</th>
                  <th>分类</th>
                  <th>排序</th>
                </tr>
              </thead>
              <tbody>
                {entries.map((entry) => (
                  <tr key={entry.id}>
                    <td>
                      <button
                        className="admin-link-button"
                        type="button"
                        onClick={() => fillForm(entry)}
                      >
                        {entry.title || entry.id}
                      </button>
                    </td>
                    <td>{entry.visible ? '是' : '否'}</td>
                    <td>{entry.open ? '是' : '否'}</td>
                    <td>{entry.unifiedCreationSpec ? '是' : '否'}</td>
                    <td>{entry.categoryLabel || entry.categoryId}</td>
                    <td>{entry.sortOrder}</td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        </section>
      </div>

      {confirmDialog}
    </section>
  );
}

function sortEntries(entries: AdminCreationEntryTypeConfigPayload[]) {
  return [...entries].sort((left, right) => {
    if (left.sortOrder !== right.sortOrder) {
      return left.sortOrder - right.sortOrder;
    }
    return left.id.localeCompare(right.id);
  });
}

function parseInteger(value: string) {
  const parsed = Number.parseInt(value, 10);
  if (!Number.isFinite(parsed)) {
    return 0;
  }
  return parsed;
}

function formatUnifiedCreationSpecJson(
  spec: UnifiedCreationSpecPayload | null | undefined,
) {
  return spec ? JSON.stringify(spec, null, 2) : '';
}

function parseUnifiedCreationSpecJson(entryId: string, value: string) {
  const parsed = parseUnifiedCreationSpecSummaryJson(value);
  if (!parsed.ok || !parsed.spec) {
    return parsed;
  }
  if (parsed.spec.playId !== entryId) {
    return {ok: false as const, message: '统一创作契约 playId 必须与入口 ID 一致'};
  }
  return parsed;
}

function validateUnifiedCreationSpec(value: unknown) {
  if (!isRecord(value)) {
    return {ok: false as const, message: '统一创作契约必须是对象'};
  }

  const playId = readRequiredString(value, 'playId');
  if (!playId) {
    return {ok: false as const, message: '统一创作契约 playId 不能为空'};
  }

  const title = readRequiredString(value, 'title');
  const workspaceStage = readRequiredString(value, 'workspaceStage');
  const generationStage = readRequiredString(value, 'generationStage');
  const resultStage = readRequiredString(value, 'resultStage');
  if (!title || !workspaceStage || !generationStage || !resultStage) {
    return {ok: false as const, message: '统一创作契约标题和阶段不能为空'};
  }
  if (new Set([workspaceStage, generationStage, resultStage]).size !== 3) {
    return {ok: false as const, message: '统一创作契约阶段不能重复'};
  }

  if (!Array.isArray(value.fields) || value.fields.length === 0) {
    return {ok: false as const, message: '统一创作契约 fields 不能为空'};
  }

  const fieldIds = new Set<string>();
  const fields: UnifiedCreationFieldPayload[] = [];
  for (const item of value.fields) {
    if (!isRecord(item)) {
      return {ok: false as const, message: '统一创作契约字段必须是对象'};
    }
    const id = readRequiredString(item, 'id');
    const label = readRequiredString(item, 'label');
    if (!id || !label) {
      return {ok: false as const, message: '统一创作契约字段 id 和 label 不能为空'};
    }
    if (fieldIds.has(id)) {
      return {ok: false as const, message: `统一创作契约字段 id 重复：${id}`};
    }
    fieldIds.add(id);
    if (!isUnifiedCreationFieldKind(item.kind)) {
      return {ok: false as const, message: `统一创作契约字段 kind 非法：${id}`};
    }
    if (typeof item.required !== 'boolean') {
      return {ok: false as const, message: `统一创作契约字段 required 非法：${id}`};
    }
    fields.push({
      id,
      kind: item.kind,
      label,
      required: item.required,
    });
  }

  return {
    ok: true as const,
    spec: {
      playId,
      title,
      workspaceStage,
      generationStage,
      resultStage,
      fields,
    },
  };
}

function UnifiedCreationSpecSummary({specJson}: {specJson: string}) {
  const parsed = parseUnifiedCreationSpecSummaryJson(specJson);
  if (!parsed.ok || !parsed.spec) {
    return (
      <div className="admin-alert" role="status">
        {'message' in parsed ? parsed.message : '未配置统一创作页契约'}
      </div>
    );
  }

  return (
    <dl className="admin-info-list">
      <div>
        <dt>玩法</dt>
        <dd>{parsed.spec.playId}</dd>
      </div>
      <div>
        <dt>阶段</dt>
        <dd>
          {parsed.spec.workspaceStage} / {parsed.spec.generationStage} /{' '}
          {parsed.spec.resultStage}
        </dd>
      </div>
      <div>
        <dt>字段</dt>
        <dd>{parsed.spec.fields.map((field) => field.id).join('、')}</dd>
      </div>
    </dl>
  );
}

function parseUnifiedCreationSpecSummaryJson(value: string) {
  const trimmed = value.trim();
  if (!trimmed) {
    return {ok: true as const, spec: null};
  }

  let parsed: unknown;
  try {
    parsed = JSON.parse(trimmed);
  } catch (error) {
    return {
      ok: false as const,
      message: error instanceof Error ? `契约 JSON 非法：${error.message}` : '契约 JSON 非法',
    };
  }

  const validation = validateUnifiedCreationSpec(parsed);
  if (!validation.ok) {
    return validation;
  }

  return {ok: true as const, spec: validation.spec};
}

function readRequiredString(value: Record<string, unknown>, key: string) {
  const raw = value[key];
  return typeof raw === 'string' ? raw.trim() : '';
}

function isRecord(value: unknown): value is Record<string, unknown> {
  return typeof value === 'object' && value !== null && !Array.isArray(value);
}

function isUnifiedCreationFieldKind(
  value: unknown,
): value is UnifiedCreationFieldPayload['kind'] {
  return (
    value === 'text' ||
    value === 'select' ||
    value === 'image' ||
    value === 'audio'
  );
}
