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

import {
  listProfileRechargeProducts,
  upsertProfileRechargeProduct,
} from '../api/adminApiClient';
import type {
  ProfileMembershipTier,
  ProfileRechargeProductConfigAdminResponse,
  ProfileRechargeProductKind,
} from '../api/adminApiTypes';
import {useAdminWriteConfirm} from '../components/useAdminWriteConfirm';
import {handlePageError} from './pageUtils';

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

const productKinds: Array<{value: ProfileRechargeProductKind; label: string}> = [
  {value: 'points', label: '泥点'},
  {value: 'membership', label: '会员'},
];

const membershipTiers: Array<{value: ProfileMembershipTier; label: string}> = [
  {value: 'month', label: '月卡'},
  {value: 'season', label: '季卡'},
  {value: 'year', label: '年卡'},
];

export function AdminRechargeProductPage({
  token,
  result,
  onUnauthorized,
  onResultChange,
}: AdminRechargeProductPageProps) {
  const [entries, setEntries] = useState<
    ProfileRechargeProductConfigAdminResponse[]
  >([]);
  const [productId, setProductId] = useState('points_60');
  const [title, setTitle] = useState('60泥点');
  const [priceCents, setPriceCents] = useState('600');
  const [kind, setKind] = useState<ProfileRechargeProductKind>('points');
  const [pointsAmount, setPointsAmount] = useState('60');
  const [bonusPoints, setBonusPoints] = useState('60');
  const [durationDays, setDurationDays] = useState('0');
  const [badgeLabel, setBadgeLabel] = useState('首充双倍');
  const [description, setDescription] = useState('首充送60泥点');
  const [tier, setTier] = useState<ProfileMembershipTier>('normal');
  const [enabled, setEnabled] = useState(true);
  const [sortOrder, setSortOrder] = useState('0');
  const [isLoading, setIsLoading] = useState(false);
  const [isSaving, setIsSaving] = useState(false);
  const [listErrorMessage, setListErrorMessage] = useState('');
  const [errorMessage, setErrorMessage] = useState('');
  const {confirmWrite, confirmDialog} = useAdminWriteConfirm();

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

  async function refreshProducts() {
    setIsLoading(true);
    setListErrorMessage('');
    try {
      const response = await listProfileRechargeProducts(token);
      const sortedEntries = sortProducts(response.entries);
      setEntries(sortedEntries);
      const firstEntry = sortedEntries[0];
      if (firstEntry) {
        fillForm(firstEntry);
      }
    } 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: enabled ? '保存充值商品' : '停用充值商品',
      target: productId.trim(),
    });
    if (!confirmed) {
      return;
    }

    setIsSaving(true);
    try {
      const response = await upsertProfileRechargeProduct(token, {
        productId: productId.trim(),
        title: title.trim(),
        priceCents: parsePositiveInteger(priceCents),
        kind,
        pointsAmount: kind === 'points' ? parsePositiveInteger(pointsAmount) : 0,
        bonusPoints: kind === 'points' ? parseNonNegativeInteger(bonusPoints) : 0,
        durationDays:
          kind === 'membership' ? parsePositiveInteger(durationDays) : 0,
        badgeLabel: kind === 'points' ? badgeLabel.trim() : '',
        description: description.trim(),
        tier: kind === 'membership' ? tier : 'normal',
        enabled,
        sortOrder: parseInteger(sortOrder),
      });
      onResultChange(response);
      upsertEntry(response);
      fillForm(response);
    } catch (error: unknown) {
      handlePageError(error, onUnauthorized, setErrorMessage);
    } finally {
      setIsSaving(false);
    }
  }

  function upsertEntry(next: ProfileRechargeProductConfigAdminResponse) {
    setEntries((current) => {
      const rest = current.filter((entry) => entry.productId !== next.productId);
      return sortProducts([...rest, next]);
    });
  }

  function fillForm(entry: ProfileRechargeProductConfigAdminResponse) {
    setProductId(entry.productId);
    setTitle(entry.title);
    setPriceCents(String(entry.priceCents));
    setKind(entry.kind);
    setPointsAmount(String(entry.pointsAmount));
    setBonusPoints(String(entry.bonusPoints));
    setDurationDays(String(entry.durationDays));
    setBadgeLabel(entry.badgeLabel);
    setDescription(entry.description);
    setTier(entry.tier);
    setEnabled(entry.enabled);
    setSortOrder(String(entry.sortOrder));
  }

  return (
    <section className="admin-page admin-page-wide">
      <div className="admin-page-heading">
        <div>
          <h2>充值商品</h2>
          <p>泥点与会员档位</p>
        </div>
        <button
          className="admin-secondary-button"
          disabled={isLoading}
          type="button"
          onClick={refreshProducts}
        >
          <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>Product ID</span>
              <input
                value={productId}
                onChange={(event) => setProductId(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">
            {productKinds.map((item) => (
              <button
                data-active={kind === item.value}
                key={item.value}
                type="button"
                onClick={() => {
                  setKind(item.value);
                  if (item.value === 'points') {
                    setTier('normal');
                    setDurationDays('0');
                  } else {
                    setBonusPoints('0');
                    setPointsAmount('0');
                    setTier(tier === 'normal' ? 'month' : tier);
                  }
                }}
              >
                {item.label}
              </button>
            ))}
          </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
                min={1}
                step={1}
                type="number"
                value={priceCents}
                onChange={(event) => setPriceCents(event.target.value)}
              />
            </label>
          </div>

          {kind === 'points' ? (
            <div className="admin-form-row">
              <label className="admin-field">
                <span>基础泥点</span>
                <input
                  min={1}
                  step={1}
                  type="number"
                  value={pointsAmount}
                  onChange={(event) => setPointsAmount(event.target.value)}
                />
              </label>
              <label className="admin-field">
                <span>首充赠送</span>
                <input
                  min={0}
                  step={1}
                  type="number"
                  value={bonusPoints}
                  onChange={(event) => setBonusPoints(event.target.value)}
                />
              </label>
            </div>
          ) : (
            <div className="admin-form-row">
              <label className="admin-field">
                <span>会员档位</span>
                <select
                  value={tier}
                  onChange={(event) =>
                    setTier(event.target.value as ProfileMembershipTier)
                  }
                >
                  {membershipTiers.map((item) => (
                    <option key={item.value} value={item.value}>
                      {item.label}
                    </option>
                  ))}
                </select>
              </label>
              <label className="admin-field">
                <span>有效天数</span>
                <input
                  min={1}
                  step={1}
                  type="number"
                  value={durationDays}
                  onChange={(event) => setDurationDays(event.target.value)}
                />
              </label>
            </div>
          )}

          <div className="admin-form-row">
            <label className="admin-field">
              <span>角标</span>
              <input
                disabled={kind !== 'points'}
                value={badgeLabel}
                onChange={(event) => setBadgeLabel(event.target.value)}
              />
            </label>
            <label className="admin-field">
              <span>排序</span>
              <input
                inputMode="numeric"
                value={sortOrder}
                onChange={(event) => setSortOrder(event.target.value)}
              />
            </label>
          </div>

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

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

          <button
            className="admin-primary-button"
            disabled={isSaving || !productId.trim() || !title.trim()}
            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>
            <div className="admin-table-wrap">
              <table className="admin-table admin-table-compact">
                <thead>
                  <tr>
                    <th>商品</th>
                    <th>类型</th>
                    <th>价格</th>
                    <th>内容</th>
                    <th>状态</th>
                  </tr>
                </thead>
                <tbody>
                  {entries.map((entry) => (
                    <tr key={entry.productId}>
                      <td>
                        <button
                          className="admin-text-button"
                          type="button"
                          onClick={() => fillForm(entry)}
                        >
                          {entry.title || entry.productId}
                        </button>
                        <small>{entry.productId}</small>
                      </td>
                      <td>{formatProductKind(entry.kind)}</td>
                      <td>{formatPrice(entry.priceCents)}</td>
                      <td>{formatProductContent(entry)}</td>
                      <td>{entry.enabled ? '启用' : '停用'}</td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          </section>

          {result ? (
            <section className="admin-panel">
              <div className="admin-panel-heading">
                <h3>最近保存</h3>
                <span>{result.updatedAt}</span>
              </div>
              <dl className="admin-info-list">
                <div>
                  <dt>商品</dt>
                  <dd>{result.productId}</dd>
                </div>
                <div>
                  <dt>状态</dt>
                  <dd>{result.enabled ? '启用' : '停用'}</dd>
                </div>
              </dl>
            </section>
          ) : null}
        </div>
      </div>

      {confirmDialog}
    </section>
  );
}

function sortProducts(entries: ProfileRechargeProductConfigAdminResponse[]) {
  return [...entries].sort((left, right) => {
    if (left.sortOrder !== right.sortOrder) {
      return left.sortOrder - right.sortOrder;
    }
    return left.productId.localeCompare(right.productId);
  });
}

function formatProductKind(kind: ProfileRechargeProductKind) {
  return kind === 'points' ? '泥点' : '会员';
}

function formatTier(tier: ProfileMembershipTier) {
  if (tier === 'month') {
    return '月卡';
  }
  if (tier === 'season') {
    return '季卡';
  }
  if (tier === 'year') {
    return '年卡';
  }
  return '普通';
}

function formatProductContent(entry: ProfileRechargeProductConfigAdminResponse) {
  if (entry.kind === 'points') {
    return `${entry.pointsAmount}+${entry.bonusPoints}`;
  }
  return `${formatTier(entry.tier)} ${entry.durationDays}天`;
}

function formatPrice(priceCents: number) {
  return `¥${(priceCents / 100).toFixed(2)}`;
}

function parsePositiveInteger(value: string) {
  const parsed = parseInteger(value);
  return parsed > 0 ? parsed : 0;
}

function parseNonNegativeInteger(value: string) {
  const parsed = parseInteger(value);
  return parsed > 0 ? parsed : 0;
}

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