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

import {
  disableProfileTaskConfig,
  listProfileTaskConfigs,
  upsertProfileTaskConfig,
} from '../api/adminApiClient';
import type {
  ProfileTaskConfigAdminResponse,
  ProfileTaskCycle,
  TrackingScopeKind,
} from '../api/adminApiTypes';
import {useAdminWriteConfirm} from '../components/useAdminWriteConfirm';
import {
  filterAdminTrackingEventDefinitions,
  findAdminTrackingEventDefinition,
} from '../config/trackingEventDefinitions';
import {handlePageError} from './pageUtils';

interface AdminTaskConfigPageProps {
  token: string;
  result: ProfileTaskConfigAdminResponse | null;
  onUnauthorized: (message?: string) => void;
  onResultChange: (result: ProfileTaskConfigAdminResponse) => void;
}

const taskCycles: Array<{value: ProfileTaskCycle; label: string}> = [
  {value: 'daily', label: '每日'},
];

const profileTaskScopeKind = 'user' satisfies TrackingScopeKind;

export function AdminTaskConfigPage({
  token,
  result,
  onUnauthorized,
  onResultChange,
}: AdminTaskConfigPageProps) {
  const [entries, setEntries] = useState<ProfileTaskConfigAdminResponse[]>([]);
  const [taskId, setTaskId] = useState('daily_login');
  const [title, setTitle] = useState('每日登录');
  const [description, setDescription] = useState('');
  const [eventKey, setEventKey] = useState('daily_login');
  const [eventKeySearch, setEventKeySearch] = useState('每日登录');
  const [isEventKeyPickerOpen, setIsEventKeyPickerOpen] = useState(false);
  const [cycle, setCycle] = useState<ProfileTaskCycle>('daily');
  const [threshold, setThreshold] = useState('1');
  const [rewardPoints, setRewardPoints] = useState('10');
  const [sortOrder, setSortOrder] = useState('10');
  const [enabled, setEnabled] = useState(true);
  const [disableTaskId, setDisableTaskId] = useState('daily_login');
  const [errorMessage, setErrorMessage] = useState('');
  const [disableErrorMessage, setDisableErrorMessage] = useState('');
  const [listErrorMessage, setListErrorMessage] = useState('');
  const [isSaving, setIsSaving] = useState(false);
  const [isDisabling, setIsDisabling] = useState(false);
  const [isLoading, setIsLoading] = useState(false);
  const {confirmWrite, confirmDialog} = useAdminWriteConfirm();

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

  const selectedEventDefinition = useMemo(
    () => findAdminTrackingEventDefinition(eventKey),
    [eventKey],
  );
  const filteredEventDefinitions = useMemo(
    () => filterAdminTrackingEventDefinitions(eventKeySearch),
    [eventKeySearch],
  );

  async function refreshTaskConfigs() {
    setIsLoading(true);
    setListErrorMessage('');
    try {
      const response = await listProfileTaskConfigs(token);
      setEntries(response.entries);
      const dailyLogin = response.entries.find(
        (entry) => entry.taskId === 'daily_login',
      );
      if (dailyLogin) {
        fillForm(dailyLogin);
      }
    } catch (error: unknown) {
      handlePageError(error, onUnauthorized, setListErrorMessage);
    } finally {
      setIsLoading(false);
    }
  }

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

    setErrorMessage('');
    const confirmed = await confirmWrite({
      action: '保存任务配置',
      target: taskId.trim(),
    });
    if (!confirmed) {
      return;
    }

    setIsSaving(true);
    try {
      const response = await upsertProfileTaskConfig(token, {
        taskId: taskId.trim(),
        title: title.trim(),
        description,
        eventKey: eventKey.trim(),
        cycle,
        scopeKind: profileTaskScopeKind,
        threshold: parsePositiveInteger(threshold),
        rewardPoints: parsePositiveInteger(rewardPoints),
        enabled,
        sortOrder: parseInteger(sortOrder),
      });
      onResultChange(response);
      upsertEntry(response);
    } catch (error: unknown) {
      handlePageError(error, onUnauthorized, setErrorMessage);
    } finally {
      setIsSaving(false);
    }
  }

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

    setDisableErrorMessage('');
    const confirmed = await confirmWrite({
      action: '停用任务配置',
      target: disableTaskId.trim(),
    });
    if (!confirmed) {
      return;
    }

    setIsDisabling(true);
    try {
      const response = await disableProfileTaskConfig(token, {
        taskId: disableTaskId.trim(),
      });
      onResultChange(response);
      upsertEntry(response);
      fillForm(response);
    } catch (error: unknown) {
      handlePageError(error, onUnauthorized, setDisableErrorMessage);
    } finally {
      setIsDisabling(false);
    }
  }

  function upsertEntry(next: ProfileTaskConfigAdminResponse) {
    setEntries((current) => {
      const rest = current.filter((entry) => entry.taskId !== next.taskId);
      return [...rest, next].sort((left, right) => {
        if (left.sortOrder !== right.sortOrder) {
          return left.sortOrder - right.sortOrder;
        }
        return left.taskId.localeCompare(right.taskId);
      });
    });
  }

  function fillForm(entry: ProfileTaskConfigAdminResponse) {
    setTaskId(entry.taskId);
    setTitle(entry.title);
    setDescription(entry.description);
    setEventKey(entry.eventKey);
    setCycle(entry.cycle);
    setThreshold(String(entry.threshold));
    setRewardPoints(String(entry.rewardPoints));
    setSortOrder(String(entry.sortOrder));
    setEnabled(entry.enabled);
    setDisableTaskId(entry.taskId);
    const nextDefinition = findAdminTrackingEventDefinition(entry.eventKey);
    setEventKeySearch(nextDefinition?.title ?? entry.eventKey);
    setIsEventKeyPickerOpen(false);
  }

  function selectEventKey(nextEventKey: string) {
    const nextDefinition = findAdminTrackingEventDefinition(nextEventKey);
    setEventKey(nextEventKey);
    if (nextDefinition) {
      setEventKeySearch(nextDefinition.title);
    } else {
      setEventKeySearch(nextEventKey);
    }
    setIsEventKeyPickerOpen(false);
  }

  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={refreshTaskConfigs}
        >
          <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>Task ID</span>
              <input
                value={taskId}
                onChange={(event) => setTaskId(event.target.value)}
              />
            </label>
            <label className="admin-switch-field">
              <input
                checked={enabled}
                type="checkbox"
                onChange={(event) => setEnabled(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>Event Key</span>
              <div
                className="admin-combobox"
                onBlur={(event) => {
                  const nextTarget = event.relatedTarget;
                  if (
                    !(nextTarget instanceof Node) ||
                    !event.currentTarget.contains(nextTarget)
                  ) {
                    setIsEventKeyPickerOpen(false);
                  }
                }}
              >
                <div className="admin-combobox-control">
                  <input
                    aria-label="Event Key"
                    value={eventKeySearch || eventKey}
                    onChange={(event) => {
                      const nextValue = event.target.value;
                      setEventKeySearch(nextValue);
                      setIsEventKeyPickerOpen(true);
                    }}
                    onFocus={() => setIsEventKeyPickerOpen(true)}
                  />
                  <button
                    aria-label="展开 Event Key"
                    className="admin-combobox-toggle"
                    type="button"
                    onClick={() =>
                      setIsEventKeyPickerOpen((current) => !current)
                    }
                  >
                    <ChevronDown size={16} aria-hidden="true" />
                  </button>
                </div>
                {isEventKeyPickerOpen ? (
                  <div className="admin-combobox-menu" role="listbox">
                    {filteredEventDefinitions.length ? (
                      filteredEventDefinitions.map((definition) => (
                        <button
                          key={definition.key}
                          className="admin-combobox-option"
                          type="button"
                          onMouseDown={(event) => event.preventDefault()}
                          onClick={() => selectEventKey(definition.key)}
                        >
                          <strong>{definition.title}</strong>
                          <span>{definition.key}</span>
                          <small>{definition.remark}</small>
                        </button>
                      ))
                    ) : (
                      <div className="admin-combobox-empty">
                        没有匹配项
                        {eventKeySearch.trim() ? (
                          <button
                            className="admin-text-button"
                            type="button"
                            onMouseDown={(event) => event.preventDefault()}
                            onClick={() =>
                              selectEventKey(eventKeySearch.trim())
                            }
                          >
                            使用自定义 key
                          </button>
                        ) : null}
                      </div>
                    )}
                  </div>
                ) : null}
              </div>
              {selectedEventDefinition ? (
                <small className="admin-field-note">
                  {selectedEventDefinition.remark}
                </small>
              ) : (
                <small className="admin-field-note">
                  自定义埋点 key，保存前请确认后端已有对应埋点写入。
                </small>
              )}
            </label>
          </div>

          <label className="admin-field">
            <span>描述</span>
            <textarea
              rows={3}
              value={description}
              onChange={(event) => setDescription(event.target.value)}
            />
          </label>

          <div className="admin-form-row">
            <label className="admin-field">
              <span>周期</span>
              <select
                value={cycle}
                onChange={(event) =>
                  setCycle(event.target.value as ProfileTaskCycle)
                }
              >
                {taskCycles.map((item) => (
                  <option key={item.value} value={item.value}>
                    {item.label}
                  </option>
                ))}
              </select>
            </label>
          </div>

          <div className="admin-form-row">
            <label className="admin-field">
              <span>完成阈值</span>
              <input
                min={1}
                step={1}
                type="number"
                value={threshold}
                onChange={(event) => setThreshold(event.target.value)}
              />
            </label>
            <label className="admin-field">
              <span>奖励光点</span>
              <input
                min={1}
                step={1}
                type="number"
                value={rewardPoints}
                onChange={(event) => setRewardPoints(event.target.value)}
              />
            </label>
          </div>

          <label className="admin-field admin-field-compact">
            <span>排序</span>
            <input
              step={1}
              type="number"
              value={sortOrder}
              onChange={(event) => setSortOrder(event.target.value)}
            />
          </label>

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

          <button
            className="admin-primary-button"
            disabled={
              isSaving ||
              !taskId.trim() ||
              !title.trim() ||
              !eventKey.trim() ||
              !parsePositiveInteger(threshold) ||
              !parsePositiveInteger(rewardPoints)
            }
            type="submit"
          >
            <Save size={17} aria-hidden="true" />
            <span>{isSaving ? '保存中' : '保存'}</span>
          </button>
        </form>

        <div className="admin-stack">
          <section className="admin-panel">
            <div className="admin-panel-heading">
              <h3>配置列表</h3>
              <span>{entries.length}</span>
            </div>
            {entries.length ? (
              <div className="admin-table-wrap">
                <table className="admin-table admin-table-compact">
                  <thead>
                    <tr>
                      <th>任务</th>
                      <th>奖励</th>
                      <th>状态</th>
                    </tr>
                  </thead>
                  <tbody>
                    {entries.map((entry) => (
                      <tr key={entry.taskId}>
                        <td>
                          <button
                            className="admin-text-button"
                            type="button"
                            onClick={() => fillForm(entry)}
                          >
                            {entry.title || entry.taskId}
                          </button>
                          <small>{entry.taskId}</small>
                        </td>
                        <td>{entry.rewardPoints}</td>
                        <td>{entry.enabled ? '启用' : '停用'}</td>
                      </tr>
                    ))}
                  </tbody>
                </table>
              </div>
            ) : (
              <div className="admin-empty-state">
                {isLoading ? '加载中' : '暂无配置'}
              </div>
            )}
          </section>

          <form className="admin-panel admin-form" onSubmit={handleDisable}>
            <label className="admin-field">
              <span>停用 Task ID</span>
              <input
                value={disableTaskId}
                onChange={(event) => setDisableTaskId(event.target.value)}
              />
            </label>
            {disableErrorMessage ? (
              <div className="admin-alert" role="status">
                {disableErrorMessage}
              </div>
            ) : null}
            <button
              className="admin-danger-button"
              disabled={isDisabling || !disableTaskId.trim()}
              type="submit"
            >
              <PowerOff size={17} aria-hidden="true" />
              <span>{isDisabling ? '停用中' : '停用'}</span>
            </button>
          </form>

          <section className="admin-panel admin-result-panel">
            <div className="admin-panel-heading">
              <h3>记录</h3>
              <span>{result?.taskId ?? '-'}</span>
            </div>
            {result ? (
              <dl className="admin-info-list">
                <div>
                  <dt>Task ID</dt>
                  <dd>{result.taskId}</dd>
                </div>
                <div>
                  <dt>Event Key</dt>
                  <dd>{result.eventKey}</dd>
                </div>
                <div>
                  <dt>奖励</dt>
                  <dd>{result.rewardPoints}</dd>
                </div>
                <div>
                  <dt>阈值</dt>
                  <dd>{result.threshold}</dd>
                </div>
                <div>
                  <dt>状态</dt>
                  <dd>{result.enabled ? '启用' : '停用'}</dd>
                </div>
                <div>
                  <dt>更新人</dt>
                  <dd>{result.updatedBy}</dd>
                </div>
                <div>
                  <dt>更新</dt>
                  <dd>{result.updatedAt}</dd>
                </div>
              </dl>
            ) : (
              <div className="admin-empty-state">暂无记录</div>
            )}
          </section>
        </div>
      </div>
      {confirmDialog}
    </section>
  );
}

function parsePositiveInteger(value: string) {
  const parsed = Number.parseInt(value, 10);
  return Number.isFinite(parsed) && parsed > 0 ? parsed : 0;
}

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