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

import {
  listProfileInviteCodes,
  upsertProfileInviteCode,
} from '../api/adminApiClient';
import type {
  AdminUpsertProfileInviteCodeRequest,
  ProfileInviteCodeAdminResponse,
} from '../api/adminApiTypes';
import {useAdminWriteConfirm} from '../components/useAdminWriteConfirm';
import {handlePageError} from './pageUtils';

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

export function AdminInviteCodePage({
  token,
  result,
  onUnauthorized,
  onResultChange,
}: AdminInviteCodePageProps) {
  const [inviteCode, setInviteCode] = useState('');
  const [startsAt, setStartsAt] = useState('');
  const [expiresAt, setExpiresAt] = useState('');
  const [grantedTagsText, setGrantedTagsText] = useState('');
  const [metadataText, setMetadataText] = useState('{}');
  const [errorMessage, setErrorMessage] = useState('');
  const [listErrorMessage, setListErrorMessage] = useState('');
  const [entries, setEntries] = useState<ProfileInviteCodeAdminResponse[]>([]);
  const [isSaving, setIsSaving] = useState(false);
  const [isLoading, setIsLoading] = useState(false);
  const {confirmWrite, confirmDialog} = useAdminWriteConfirm();

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

  async function refreshInviteCodes() {
    setIsLoading(true);
    setListErrorMessage('');
    try {
      const response = await listProfileInviteCodes(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 validityError = validateValidityWindow(startsAt, expiresAt);
    if (validityError) {
      setErrorMessage(validityError);
      return;
    }

    const confirmed = await confirmWrite({
      action: '保存邀请码',
      target: inviteCode.trim(),
    });
    if (!confirmed) {
      return;
    }

    setIsSaving(true);
    try {
      const metadata = withMetadataUserTags(
        parseMetadata(metadataText),
        parseUserTags(grantedTagsText),
      );
      const payload: AdminUpsertProfileInviteCodeRequest = {
        inviteCode: inviteCode.trim(),
        metadata,
        startsAt: startsAt ? toIsoDateTime(startsAt) : null,
        expiresAt: expiresAt ? toIsoDateTime(expiresAt) : null,
      };
      const response = await upsertProfileInviteCode(token, payload);
      onResultChange(response);
      upsertEntry(response);
      fillForm(response);
    } catch (error: unknown) {
      handlePageError(error, onUnauthorized, setErrorMessage);
    } finally {
      setIsSaving(false);
    }
  }

  function upsertEntry(next: ProfileInviteCodeAdminResponse) {
    setEntries((current) => {
      const rest = current.filter((entry) => entry.inviteCode !== next.inviteCode);
      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.inviteCode.localeCompare(right.inviteCode);
      });
    });
  }

  function fillForm(entry: ProfileInviteCodeAdminResponse) {
    setInviteCode(entry.inviteCode);
    setStartsAt(toDateTimeLocalValue(entry.startsAt));
    setExpiresAt(toDateTimeLocalValue(entry.expiresAt));
    setGrantedTagsText(metadataUserTags(entry.metadata).join('、'));
    setMetadataText(JSON.stringify(entry.metadata, null, 2));
  }

  const validityError = validateValidityWindow(startsAt, expiresAt);

  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={refreshInviteCodes}
        >
          <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}>
          <label className="admin-field">
            <span>Invite Code</span>
            <input
              autoComplete="off"
              value={inviteCode}
              onChange={(event) => setInviteCode(event.target.value)}
            />
          </label>

          <div className="admin-form-row">
            <label className="admin-field">
              <span>开始时间</span>
              <input
                type="datetime-local"
                value={startsAt}
                onChange={(event) => setStartsAt(event.target.value)}
              />
            </label>
            <label className="admin-field">
              <span>截止时间</span>
              <input
                type="datetime-local"
                value={expiresAt}
                onChange={(event) => setExpiresAt(event.target.value)}
              />
            </label>
          </div>

          <label className="admin-field">
            <span>用户标签</span>
            <input
              autoComplete="off"
              value={grantedTagsText}
              onChange={(event) => setGrantedTagsText(event.target.value)}
            />
          </label>

          <label className="admin-field">
            <span>Metadata JSON</span>
            <textarea
              rows={10}
              spellCheck={false}
              value={metadataText}
              onChange={(event) => setMetadataText(event.target.value)}
            />
          </label>

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

          <button
            className="admin-primary-button"
            disabled={
              isSaving ||
              !inviteCode.trim() ||
              !isMetadataReady(metadataText) ||
              Boolean(validityError)
            }
            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>
                      <th>创建</th>
                    </tr>
                  </thead>
                  <tbody>
                    {entries.map((entry) => (
                      <tr key={entry.inviteCode}>
                        <td>
                          <button
                            className="admin-text-button"
                            type="button"
                            onClick={() => fillForm(entry)}
                          >
                            {entry.inviteCode}
                          </button>
                        </td>
                        <td>
                          <TagList tags={metadataUserTags(entry.metadata)} />
                        </td>
                        <td>
                          <span className={`admin-status ${inviteValidityClass(entry)}`}>
                            {inviteValidityLabel(entry)}
                          </span>
                          <small>{formatValidityWindow(entry)}</small>
                        </td>
                        <td>{entry.createdAt}</td>
                      </tr>
                    ))}
                  </tbody>
                </table>
              </div>
            ) : (
              <div className="admin-empty-state">
                {isLoading ? '加载中' : '暂无邀请码'}
              </div>
            )}
          </section>

          <section className="admin-panel admin-result-panel">
            <div className="admin-panel-heading">
              <h3>记录</h3>
              <span>{result?.inviteCode ?? '-'}</span>
            </div>
            {result ? (
              <dl className="admin-info-list">
                <div>
                  <dt>邀请码</dt>
                  <dd>{result.inviteCode}</dd>
                </div>
                <div>
                  <dt>有效期</dt>
                  <dd>{formatValidityWindow(result)}</dd>
                </div>
                <div>
                  <dt>标签</dt>
                  <dd>
                    <TagList tags={metadataUserTags(result.metadata)} />
                  </dd>
                </div>
                <div>
                  <dt>创建</dt>
                  <dd>{result.createdAt}</dd>
                </div>
                <div>
                  <dt>更新</dt>
                  <dd>{result.updatedAt}</dd>
                </div>
                <div>
                  <dt>Metadata</dt>
                  <dd>
                    <pre className="admin-code-block">
                      {JSON.stringify(result.metadata, null, 2)}
                    </pre>
                  </dd>
                </div>
              </dl>
            ) : (
              <div className="admin-empty-state">暂无记录</div>
            )}
          </section>
        </div>
      </div>
      {confirmDialog}
    </section>
  );
}

function TagList({tags}: {tags: string[]}) {
  if (!tags.length) {
    return <span className="admin-muted-text">-</span>;
  }

  return (
    <span className="admin-tag-list">
      {tags.map((tag) => (
        <span className="admin-tag" key={tag}>
          {tag}
        </span>
      ))}
    </span>
  );
}

function metadataUserTags(metadata: Record<string, unknown>) {
  const raw = metadata.userTags ?? metadata.user_tags;
  if (!Array.isArray(raw)) {
    return [];
  }

  return parseUserTags(raw.filter((value): value is string => typeof value === 'string').join('、'));
}

function withMetadataUserTags(
  metadata: Record<string, unknown>,
  tags: string[],
): Record<string, unknown> {
  const next = {...metadata};
  delete next.user_tags;
  if (tags.length) {
    next.userTags = tags;
  } else {
    delete next.userTags;
  }
  return next;
}

function parseUserTags(value: string) {
  const tags: string[] = [];
  for (const raw of value.split(/[\n,，;；、]+/)) {
    const tag = raw.trim();
    if (tag && !tags.includes(tag)) {
      tags.push(tag);
    }
  }
  return tags;
}

function parseMetadata(value: string): Record<string, unknown> {
  const trimmed = value.trim();
  if (!trimmed) {
    return {};
  }

  const parsed = JSON.parse(trimmed) as unknown;
  if (!isRecord(parsed)) {
    throw new Error('Metadata 必须是 JSON 对象');
  }
  return parsed;
}

function isMetadataReady(value: string) {
  try {
    parseMetadata(value);
    return true;
  } catch {
    return false;
  }
}

function validateValidityWindow(startsAt: string, expiresAt: string) {
  if (!startsAt || !expiresAt) {
    return '';
  }

  const startsAtTime = Date.parse(toIsoDateTime(startsAt));
  const expiresAtTime = Date.parse(toIsoDateTime(expiresAt));
  if (!Number.isFinite(startsAtTime) || !Number.isFinite(expiresAtTime)) {
    return '有效期时间无效';
  }

  return startsAtTime < expiresAtTime ? '' : '截止时间必须晚于开始时间';
}

function toIsoDateTime(value: string) {
  const time = Date.parse(value);
  if (!Number.isFinite(time)) {
    throw new Error('有效期时间无效');
  }
  return new Date(time).toISOString();
}

function toDateTimeLocalValue(value?: string | null) {
  if (!value) {
    return '';
  }

  const date = new Date(value);
  if (!Number.isFinite(date.getTime())) {
    return '';
  }

  const offsetMs = date.getTimezoneOffset() * 60 * 1000;
  return new Date(date.getTime() - offsetMs).toISOString().slice(0, 16);
}

function inviteValidityLabel(entry: ProfileInviteCodeAdminResponse) {
  const now = Date.now();
  const startsAtTime = entry.startsAt ? Date.parse(entry.startsAt) : null;
  const expiresAtTime = entry.expiresAt ? Date.parse(entry.expiresAt) : null;

  if (startsAtTime && Number.isFinite(startsAtTime) && now < startsAtTime) {
    return '未生效';
  }
  if (expiresAtTime && Number.isFinite(expiresAtTime) && now >= expiresAtTime) {
    return '已过期';
  }
  if (entry.startsAt || entry.expiresAt) {
    return '有效';
  }
  return '长期有效';
}

function inviteValidityClass(entry: ProfileInviteCodeAdminResponse) {
  const label = inviteValidityLabel(entry);
  if (label === '已过期') {
    return 'admin-status-error';
  }
  if (label === '未生效') {
    return 'admin-status-pending';
  }
  return 'admin-status-ok';
}

function formatValidityWindow(entry: ProfileInviteCodeAdminResponse) {
  const startsAt = entry.startsAt ? formatDateTime(entry.startsAt) : '立即';
  const expiresAt = entry.expiresAt ? formatDateTime(entry.expiresAt) : '长期';
  return `${startsAt} / ${expiresAt}`;
}

function formatDateTime(value: string) {
  const date = new Date(value);
  if (!Number.isFinite(date.getTime())) {
    return value;
  }
  return date.toLocaleString('zh-CN', {hour12: false});
}

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