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

import {
  disableProfileRedeemCode,
  listProfileRedeemCodes,
  upsertProfileRedeemCode,
} from '../api/adminApiClient';
import type {
  ProfileRedeemCodeAdminResponse,
  ProfileRedeemCodeMode,
} from '../api/adminApiTypes';
import {useAdminWriteConfirm} from '../components/useAdminWriteConfirm';
import {handlePageError, splitLines} from './pageUtils';

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

const redeemModes: Array<{value: ProfileRedeemCodeMode; label: string}> = [
  {value: 'public', label: '公共码'},
  {value: 'unique', label: '唯一码'},
  {value: 'private', label: '私有码'},
];

export function AdminRedeemCodePage({
  token,
  result,
  onUnauthorized,
  onResultChange,
}: AdminRedeemCodePageProps) {
  const [code, setCode] = useState('');
  const [mode, setMode] = useState<ProfileRedeemCodeMode>('public');
  const [rewardPoints, setRewardPoints] = useState('100');
  const [maxUses, setMaxUses] = useState('1');
  const [enabled, setEnabled] = useState(true);
  const [allowedUserIds, setAllowedUserIds] = useState('');
  const [allowedPublicUserCodes, setAllowedPublicUserCodes] = useState('');
  const [disableCode, setDisableCode] = useState('');
  const [errorMessage, setErrorMessage] = useState('');
  const [disableErrorMessage, setDisableErrorMessage] = useState('');
  const [listErrorMessage, setListErrorMessage] = useState('');
  const [entries, setEntries] = useState<ProfileRedeemCodeAdminResponse[]>([]);
  const [isSaving, setIsSaving] = useState(false);
  const [isDisabling, setIsDisabling] = useState(false);
  const [isLoading, setIsLoading] = useState(false);
  const {confirmWrite, confirmDialog} = useAdminWriteConfirm();

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

  async function refreshRedeemCodes() {
    setIsLoading(true);
    setListErrorMessage('');
    try {
      const response = await listProfileRedeemCodes(token);
      setEntries(response.entries);
    } 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: code.trim(),
    });
    if (!confirmed) {
      return;
    }

    setIsSaving(true);
    try {
      const response = await upsertProfileRedeemCode(token, {
        code: code.trim(),
        mode,
        rewardPoints: parsePositiveInteger(rewardPoints),
        maxUses: parsePositiveInteger(maxUses),
        enabled,
        allowedUserIds: mode === 'private' ? splitLines(allowedUserIds) : [],
        allowedPublicUserCodes:
          mode === 'private' ? splitLines(allowedPublicUserCodes) : [],
      });
      onResultChange(response);
      upsertEntry(response);
      fillForm(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: disableCode.trim(),
    });
    if (!confirmed) {
      return;
    }

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

  function upsertEntry(next: ProfileRedeemCodeAdminResponse) {
    setEntries((current) => {
      const rest = current.filter((entry) => entry.code !== next.code);
      return [...rest, next].sort((left, right) => {
        const leftUpdatedAt = Date.parse(left.updatedAt);
        const rightUpdatedAt = Date.parse(right.updatedAt);
        if (Number.isFinite(leftUpdatedAt) && Number.isFinite(rightUpdatedAt)) {
          const updatedCompare = rightUpdatedAt - leftUpdatedAt;
          if (updatedCompare !== 0) {
            return updatedCompare;
          }
        }
        return left.code.localeCompare(right.code);
      });
    });
  }

  function fillForm(entry: ProfileRedeemCodeAdminResponse) {
    setCode(entry.code);
    setMode(entry.mode);
    setRewardPoints(String(entry.rewardPoints));
    setMaxUses(String(entry.maxUses));
    setEnabled(entry.enabled);
    setAllowedUserIds(entry.allowedUserIds.join('\n'));
    setAllowedPublicUserCodes('');
    setDisableCode(entry.code);
  }

  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={refreshRedeemCodes}
        >
          <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>Code</span>
              <input
                value={code}
                onChange={(event) => setCode(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-segmented-control" role="tablist">
            {redeemModes.map((item) => (
              <button
                data-active={mode === item.value}
                key={item.value}
                type="button"
                onClick={() => setMode(item.value)}
              >
                {item.label}
              </button>
            ))}
          </div>

          <div className="admin-form-row">
            <label className="admin-field">
              <span>奖励点数</span>
              <input
                min={1}
                step={1}
                type="number"
                value={rewardPoints}
                onChange={(event) => setRewardPoints(event.target.value)}
              />
            </label>
            <label className="admin-field">
              <span>最大次数</span>
              <input
                min={1}
                step={1}
                type="number"
                value={maxUses}
                onChange={(event) => setMaxUses(event.target.value)}
              />
            </label>
          </div>

          {mode === 'private' ? (
            <div className="admin-form-row">
              <label className="admin-field">
                <span>内部 userId</span>
                <textarea
                  rows={6}
                  value={allowedUserIds}
                  onChange={(event) => setAllowedUserIds(event.target.value)}
                />
              </label>
              <label className="admin-field">
                <span>公开百梦号</span>
                <textarea
                  rows={6}
                  value={allowedPublicUserCodes}
                  onChange={(event) =>
                    setAllowedPublicUserCodes(event.target.value)
                  }
                />
              </label>
            </div>
          ) : null}

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

          <button
            className="admin-primary-button"
            disabled={
              isSaving ||
              !code.trim() ||
              !parsePositiveInteger(rewardPoints) ||
              !parsePositiveInteger(maxUses)
            }
            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>Code</th>
                      <th>奖励</th>
                      <th>状态</th>
                    </tr>
                  </thead>
                  <tbody>
                    {entries.map((entry) => (
                      <tr key={entry.code}>
                        <td>
                          <button
                            className="admin-text-button"
                            type="button"
                            onClick={() => fillForm(entry)}
                          >
                            {entry.code}
                          </button>
                          <small>{redeemModeLabel(entry.mode)}</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>停用 Code</span>
              <input
                value={disableCode}
                onChange={(event) => setDisableCode(event.target.value)}
              />
            </label>
            {disableErrorMessage ? (
              <div className="admin-alert" role="status">
                {disableErrorMessage}
              </div>
            ) : null}
            <button
              className="admin-danger-button"
              disabled={isDisabling || !disableCode.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?.mode ?? '-'}</span>
            </div>
            {result ? (
              <dl className="admin-info-list">
                <div>
                  <dt>Code</dt>
                  <dd>{result.code}</dd>
                </div>
                <div>
                  <dt>奖励</dt>
                  <dd>{result.rewardPoints}</dd>
                </div>
                <div>
                  <dt>最大次数</dt>
                  <dd>{result.maxUses}</dd>
                </div>
                <div>
                  <dt>全局已用</dt>
                  <dd>{result.globalUsedCount}</dd>
                </div>
                <div>
                  <dt>状态</dt>
                  <dd>{result.enabled ? '启用' : '停用'}</dd>
                </div>
                <div>
                  <dt>创建人</dt>
                  <dd>{result.createdBy}</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 redeemModeLabel(value: ProfileRedeemCodeMode) {
  return redeemModes.find((item) => item.value === value)?.label ?? value;
}
