import { useCallback, useEffect, useMemo, useState } from 'react';
import {
  createSystemTestAccount,
  deleteSystemTestAccount,
  listSkillCatalog,
  listSystemTestAccounts,
  runSystemSkillValidation,
} from '../../api/client';
import type { AdminSystemTestAccount, AdminSystemTestReport, SkillDefinition } from '../../types';
import { formatTime } from '../utils/format';

const DEFAULT_SKILL = 'service-integration-smoke';

function statusLabel(status: 'passed' | 'warning' | 'failed') {
  if (status === 'passed') return '通过';
  if (status === 'warning') return '待处理';
  return '失败';
}

function AddAccountModal({
  onClose,
  onSave,
}: {
  onClose: () => void;
  onSave: (payload: { label: string; username: string; password: string }) => Promise<void>;
}) {
  const [label, setLabel] = useState('');
  const [username, setUsername] = useState('');
  const [password, setPassword] = useState('');
  const [saving, setSaving] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const handleSubmit = async (event: React.FormEvent) => {
    event.preventDefault();
    const normalizedUsername = username.trim();
    const normalizedLabel = label.trim() || normalizedUsername;
    if (!normalizedUsername || !password) return;
    setSaving(true);
    setError(null);
    try {
      await onSave({
        label: normalizedLabel,
        username: normalizedUsername,
        password,
      });
    } catch (err) {
      setError(err instanceof Error ? err.message : '保存测试账号失败');
    } finally {
      setSaving(false);
    }
  };

  return (
    <div className="modal-backdrop" onClick={(event) => event.target === event.currentTarget && onClose()}>
      <div className="modal-box" style={{ maxWidth: 520 }}>
        <div className="modal-head">
          <div>
            <h3>添加测试账号</h3>
            <p className="muted">保存到后台配置，后续管理员都可以直接复用。</p>
          </div>
          <button type="button" className="modal-close" onClick={onClose}>×</button>
        </div>
        {error && <p className="banner banner-error">{error}</p>}
        <form className="admin-form plan-form" onSubmit={handleSubmit}>
          <label className="plan-form-row">
            <span>显示名称</span>
            <input
              type="text"
              value={label}
              onChange={(event) => setLabel(event.target.value)}
              placeholder="例如 John 测试号"
            />
          </label>
          <label className="plan-form-row">
            <span>账号</span>
            <input
              type="text"
              value={username}
              onChange={(event) => setUsername(event.target.value)}
              placeholder="例如 john"
              autoComplete="username"
              required
            />
          </label>
          <label className="plan-form-row">
            <span>密码</span>
            <input
              type="password"
              value={password}
              onChange={(event) => setPassword(event.target.value)}
              placeholder="输入该账号密码"
              autoComplete="current-password"
              required
            />
          </label>
          <div className="plan-form-actions">
            <button type="button" className="admin-btn-secondary" onClick={onClose} disabled={saving}>取消</button>
            <button type="submit" className="send-btn" disabled={saving || !username.trim() || !password}>
              {saving ? '保存中…' : '保存账号'}
            </button>
          </div>
        </form>
      </div>
    </div>
  );
}

export function SystemTestsPage() {
  const [catalog, setCatalog] = useState<SkillDefinition[]>([]);
  const [skillName, setSkillName] = useState(DEFAULT_SKILL);
  const [accounts, setAccounts] = useState<AdminSystemTestAccount[]>([]);
  const [selectedAccountId, setSelectedAccountId] = useState('');
  const [loading, setLoading] = useState(true);
  const [running, setRunning] = useState(false);
  const [accountsLoading, setAccountsLoading] = useState(true);
  const [accountBusyId, setAccountBusyId] = useState<string | null>(null);
  const [showAddAccount, setShowAddAccount] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [report, setReport] = useState<AdminSystemTestReport | null>(null);

  const loadCatalog = useCallback(async () => {
    setLoading(true);
    setError(null);
    try {
      const nextCatalog = await listSkillCatalog();
      setCatalog(nextCatalog);
      if (nextCatalog.some((item) => item.name === DEFAULT_SKILL)) {
        setSkillName(DEFAULT_SKILL);
      } else if (nextCatalog[0]?.name) {
        setSkillName(nextCatalog[0].name);
      }
    } catch (err) {
      setError(err instanceof Error ? err.message : '加载 skill 列表失败');
    } finally {
      setLoading(false);
    }
  }, []);

  useEffect(() => {
    void loadCatalog();
  }, [loadCatalog]);

  const loadAccounts = useCallback(async () => {
    setAccountsLoading(true);
    try {
      const nextAccounts = await listSystemTestAccounts();
      setAccounts(nextAccounts);
      setSelectedAccountId((current) =>
        nextAccounts.some((item) => item.id === current) ? current : (nextAccounts[0]?.id ?? ''),
      );
    } catch (err) {
      setError(err instanceof Error ? err.message : '加载测试账号失败');
    } finally {
      setAccountsLoading(false);
    }
  }, []);

  useEffect(() => {
    void loadAccounts();
  }, [loadAccounts]);

  const selectedSkill = useMemo(
    () => catalog.find((item) => item.name === skillName) ?? null,
    [catalog, skillName],
  );

  const selectedAccount = useMemo(
    () => accounts.find((item) => item.id === selectedAccountId) ?? null,
    [accounts, selectedAccountId],
  );

  const handleSaveAccount = async (payload: { label: string; username: string; password: string }) => {
    const account = await createSystemTestAccount(payload);
    setAccounts((current) => [account, ...current]);
    setSelectedAccountId(account.id);
    setShowAddAccount(false);
  };

  const handleRemoveAccount = async () => {
    if (!selectedAccount) return;
    setAccountBusyId(selectedAccount.id);
    setError(null);
    try {
      await deleteSystemTestAccount(selectedAccount.id);
      const nextAccounts = accounts.filter((item) => item.id !== selectedAccount.id);
      setAccounts(nextAccounts);
      setSelectedAccountId(nextAccounts[0]?.id ?? '');
    } catch (err) {
      setError(err instanceof Error ? err.message : '删除测试账号失败');
    } finally {
      setAccountBusyId(null);
    }
  };

  const handleSubmit = async (event: React.FormEvent) => {
    event.preventDefault();
    if (!selectedAccount) {
      setError('请先选择一个测试账号，或先添加账号');
      return;
    }
    setRunning(true);
    setError(null);
    try {
      const nextReport = await runSystemSkillValidation({
        accountId: selectedAccount.id,
        username: '',
        password: '',
        skillName,
      });
      setReport(nextReport);
    } catch (err) {
      setError(err instanceof Error ? err.message : '系统测试执行失败');
    } finally {
      setRunning(false);
    }
  };

  return (
    <div className="admin-page">
      <div className="admin-page-head">
        <h2>系统测试验证</h2>
        <p className="muted">选择测试账号后，按选定 skill 执行整条服务联调，并汇总异常反馈。</p>
      </div>

      {error && <p className="banner banner-error">{error}</p>}

      <section className="admin-card">
        <div className="admin-card-head">
          <div>
            <h2>执行参数</h2>
            <p className="muted">默认推荐使用 service-integration-smoke，对真实账号跑登录、直连聊天、记忆读取和 skill 输出验证。</p>
          </div>
        </div>
        {loading ? (
          <p className="muted">加载 skill 列表中…</p>
        ) : (
          <form className="admin-form" onSubmit={handleSubmit}>
            <label>
              <span>验证 Skill</span>
              <select value={skillName} onChange={(e) => setSkillName(e.target.value)} className="admin-select">
                {catalog.map((item) => (
                  <option key={item.name} value={item.name}>
                    {item.label}
                  </option>
                ))}
              </select>
            </label>
            <div className="form-span-all system-test-account-panel">
              <label className="system-test-account-select">
                <span>测试账号</span>
                <select
                  value={selectedAccountId}
                  onChange={(event) => setSelectedAccountId(event.target.value)}
                  className="admin-select"
                  disabled={accounts.length === 0 || accountsLoading}
                >
                  {accountsLoading ? (
                    <option value="">加载测试账号中…</option>
                  ) : accounts.length === 0 ? (
                    <option value="">请先添加测试账号</option>
                  ) : (
                    accounts.map((account) => (
                      <option key={account.id} value={account.id}>
                        {account.label} ({account.username})
                      </option>
                    ))
                  )}
                </select>
              </label>
              <div className="system-test-account-actions">
                <button type="button" className="admin-btn-secondary" onClick={() => setShowAddAccount(true)}>
                  + 添加账号
                </button>
                <button
                  type="button"
                  className="admin-btn-secondary"
                  onClick={() => void handleRemoveAccount()}
                  disabled={!selectedAccount || accountBusyId === selectedAccount?.id}
                >
                  {accountBusyId === selectedAccount?.id ? '删除中…' : '删除当前账号'}
                </button>
                <button type="button" className="admin-btn-secondary" onClick={() => void loadAccounts()} disabled={accountsLoading}>
                  {accountsLoading ? '刷新中…' : '刷新账号'}
                </button>
              </div>
              {selectedAccount ? (
                <div className="system-test-account-summary muted">
                  当前使用: <strong>{selectedAccount.label}</strong> · @{selectedAccount.username} · 密码 {selectedAccount.passwordMasked}
                </div>
              ) : (
                <div className="system-test-account-summary muted">
                  还没有可用测试账号，请先添加账号和密码。
                </div>
              )}
            </div>
            {selectedSkill && (
              <p className="muted">
                当前 skill: <strong>{selectedSkill.label}</strong> · {selectedSkill.description}
              </p>
            )}
            <button type="submit" className="send-btn" disabled={running || loading}>
              {running ? '验证执行中…' : '开始验证'}
            </button>
          </form>
        )}
      </section>

      {showAddAccount && (
        <AddAccountModal
          onClose={() => setShowAddAccount(false)}
          onSave={handleSaveAccount}
        />
      )}

      {report && (
        <>
          <section className="admin-card">
            <div className="admin-card-head">
              <div>
                <h2>验证摘要</h2>
                <p className="muted">
                  账号 @{report.account.username} · skill {report.selectedSkill} · Portal {report.portalBaseUrl}
                </p>
              </div>
            </div>
            <div className="admin-stat-grid">
              <div className="admin-stat-card">
                <div className="admin-stat-label">总体结果</div>
                <div className="admin-stat-value">{report.ok ? '通过' : '有问题'}</div>
                <div className="muted">
                  开始 {formatTime(report.startedAt)} / 完成 {formatTime(report.finishedAt)}
                </div>
              </div>
              <div className="admin-stat-card">
                <div className="admin-stat-label">通过</div>
                <div className="admin-stat-value">{report.summary.passed}</div>
              </div>
              <div className="admin-stat-card">
                <div className="admin-stat-label">待处理</div>
                <div className="admin-stat-value">{report.summary.warnings}</div>
              </div>
              <div className="admin-stat-card">
                <div className="admin-stat-label">失败</div>
                <div className="admin-stat-value">{report.summary.failed}</div>
              </div>
            </div>
          </section>

          <section className="admin-card">
            <div className="admin-card-head">
              <h2>步骤结果</h2>
            </div>
            <div className="admin-table-wrap">
              <table className="admin-table">
                <thead>
                  <tr>
                    <th>步骤</th>
                    <th>状态</th>
                    <th>结果</th>
                  </tr>
                </thead>
                <tbody>
                  {report.steps.map((step) => (
                    <tr key={step.key}>
                      <td>{step.label}</td>
                      <td>{statusLabel(step.status)}</td>
                      <td>
                        <div>{step.message}</div>
                        {step.details && (
                          <details style={{ marginTop: 8 }}>
                            <summary className="muted">查看详情</summary>
                            <pre style={{ whiteSpace: 'pre-wrap', marginTop: 8 }}>
                              {JSON.stringify(step.details, null, 2)}
                            </pre>
                          </details>
                        )}
                      </td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          </section>

          <section className="admin-card">
            <div className="admin-card-head">
              <h2>问题反馈</h2>
            </div>
            {report.issues.length === 0 ? (
              <p className="muted">本轮未发现额外问题。</p>
            ) : (
              <div className="admin-table-wrap">
                <table className="admin-table">
                  <thead>
                    <tr>
                      <th>级别</th>
                      <th>步骤</th>
                      <th>问题</th>
                    </tr>
                  </thead>
                  <tbody>
                    {report.issues.map((issue, index) => (
                      <tr key={`${issue.stepKey}-${index}`}>
                        <td>{issue.severity === 'error' ? '错误' : '提醒'}</td>
                        <td>{issue.stepKey}</td>
                        <td>
                          <div>{issue.title}</div>
                          <div className="muted" style={{ marginTop: 6 }}>{issue.detail}</div>
                        </td>
                      </tr>
                    ))}
                  </tbody>
                </table>
              </div>
            )}
          </section>
        </>
      )}
    </div>
  );
}
