/**
 * 通用 UI 组件测试
 */
import { describe, expect, it, vi } from "vitest";
import { render, screen, fireEvent } from "@testing-library/react";
import {
  PaperCard,
  PageHeader,
  Button,
  Input,
  Select,
  Badge,
  Table,
  TableRow,
  TableCell,
  EmptyState,
  LoadingState,
  ErrorState,
  Pagination,
} from "./ui";

describe("PaperCard", () => {
  it("渲染 children", () => {
    render(<PaperCard>内容</PaperCard>);
    expect(screen.getByText("内容")).toBeInTheDocument();
  });

  it("支持自定义 className", () => {
    const { container } = render(
      <PaperCard className="custom-class">内容</PaperCard>,
    );
    expect(container.firstChild).toHaveClass("custom-class");
  });
});

describe("PageHeader", () => {
  it("渲染标题", () => {
    render(<PageHeader title="用户管理" />);
    expect(screen.getByText("用户管理")).toBeInTheDocument();
  });

  it("渲染描述", () => {
    render(<PageHeader title="用户管理" description="管理所有用户" />);
    expect(screen.getByText("管理所有用户")).toBeInTheDocument();
  });

  it("渲染操作按钮", () => {
    render(<PageHeader title="用户管理" actions={<button>新建</button>} />);
    expect(screen.getByText("新建")).toBeInTheDocument();
  });
});

describe("Button", () => {
  it("默认 secondary variant", () => {
    render(<Button>点击</Button>);
    expect(screen.getByText("点击")).toBeInTheDocument();
  });

  it("点击触发 onClick", () => {
    const onClick = vi.fn();
    render(<Button onClick={onClick}>点击</Button>);
    fireEvent.click(screen.getByText("点击"));
    expect(onClick).toHaveBeenCalledTimes(1);
  });

  it("disabled 时不触发 onClick", () => {
    const onClick = vi.fn();
    render(
      <Button onClick={onClick} disabled>
        点击
      </Button>,
    );
    fireEvent.click(screen.getByText("点击"));
    expect(onClick).not.toHaveBeenCalled();
  });

  it("支持所有 variant", () => {
    const { rerender } = render(<Button variant="primary">主按钮</Button>);
    expect(screen.getByText("主按钮")).toBeInTheDocument();
    rerender(<Button variant="danger">危险按钮</Button>);
    expect(screen.getByText("危险按钮")).toBeInTheDocument();
    rerender(<Button variant="ghost">幽灵按钮</Button>);
    expect(screen.getByText("幽灵按钮")).toBeInTheDocument();
  });
});

describe("Input", () => {
  it("渲染输入框并支持输入", () => {
    render(<Input placeholder="请输入" />);
    const input = screen.getByPlaceholderText("请输入");
    fireEvent.change(input, { target: { value: "测试内容" } });
    expect(input).toHaveValue("测试内容");
  });
});

describe("Select", () => {
  it("渲染下拉框和选项", () => {
    render(
      <Select>
        <option value="a">选项A</option>
        <option value="b">选项B</option>
      </Select>,
    );
    expect(screen.getByText("选项A")).toBeInTheDocument();
    expect(screen.getByText("选项B")).toBeInTheDocument();
  });
});

describe("Badge", () => {
  it("渲染 active 状态标签", () => {
    render(<Badge status="active" />);
    expect(screen.getByText("启用")).toBeInTheDocument();
  });

  it("渲染 locked 状态标签", () => {
    render(<Badge status="locked" />);
    expect(screen.getByText("锁定")).toBeInTheDocument();
  });

  it("渲染公告相关状态", () => {
    const { rerender } = render(<Badge status="draft" />);
    expect(screen.getByText("草稿")).toBeInTheDocument();
    rerender(<Badge status="published" />);
    expect(screen.getByText("已发布")).toBeInTheDocument();
    rerender(<Badge status="archived" />);
    expect(screen.getByText("已归档")).toBeInTheDocument();
  });

  it("渲染邀请码状态", () => {
    const { rerender } = render(<Badge status="unused" />);
    expect(screen.getByText("未使用")).toBeInTheDocument();
    rerender(<Badge status="used" />);
    expect(screen.getByText("已使用")).toBeInTheDocument();
    rerender(<Badge status="expired" />);
    expect(screen.getByText("已过期")).toBeInTheDocument();
  });

  it("未知状态显示原始值", () => {
    render(<Badge status="unknown-status" />);
    expect(screen.getByText("unknown-status")).toBeInTheDocument();
  });
});

describe("Table", () => {
  it("渲染表头和数据行", () => {
    render(
      <Table headers={["姓名", "邮箱"]}>
        <TableRow>
          <TableCell>张三</TableCell>
          <TableCell>zhangsan@test.com</TableCell>
        </TableRow>
      </Table>,
    );
    expect(screen.getByText("姓名")).toBeInTheDocument();
    expect(screen.getByText("邮箱")).toBeInTheDocument();
    expect(screen.getByText("张三")).toBeInTheDocument();
    expect(screen.getByText("zhangsan@test.com")).toBeInTheDocument();
  });
});

describe("EmptyState", () => {
  it("渲染空状态消息", () => {
    render(<EmptyState message="暂无数据" />);
    expect(screen.getByText("暂无数据")).toBeInTheDocument();
  });
});

describe("LoadingState", () => {
  it("渲染加载中文案", () => {
    render(<LoadingState />);
    expect(screen.getByText("加载中...")).toBeInTheDocument();
  });
});

describe("ErrorState", () => {
  it("渲染错误消息", () => {
    render(<ErrorState message="加载失败" />);
    expect(screen.getByText("加载失败")).toBeInTheDocument();
  });

  it("提供 onRetry 时渲染重试按钮", () => {
    const onRetry = vi.fn();
    render(<ErrorState message="加载失败" onRetry={onRetry} />);
    const retryBtn = screen.getByText("重试");
    fireEvent.click(retryBtn);
    expect(onRetry).toHaveBeenCalledTimes(1);
  });

  it("不提供 onRetry 时不渲染重试按钮", () => {
    render(<ErrorState message="加载失败" />);
    expect(screen.queryByText("重试")).not.toBeInTheDocument();
  });
});

describe("Pagination", () => {
  it("渲染总数和页码", () => {
    render(
      <Pagination
        page={2}
        pageSize={20}
        total={45}
        hasNext={true}
        onPageChange={() => {}}
      />,
    );
    expect(screen.getByText(/共 45 条/)).toBeInTheDocument();
    expect(screen.getByText(/第 2\/3 页/)).toBeInTheDocument();
  });

  it("第一页禁用上一页按钮", () => {
    render(
      <Pagination
        page={1}
        pageSize={20}
        total={45}
        hasNext={true}
        onPageChange={() => {}}
      />,
    );
    expect(screen.getByText("上一页")).toBeDisabled();
    expect(screen.getByText("下一页")).not.toBeDisabled();
  });

  it("最后一页禁用下一页按钮", () => {
    render(
      <Pagination
        page={3}
        pageSize={20}
        total={45}
        hasNext={false}
        onPageChange={() => {}}
      />,
    );
    expect(screen.getByText("下一页")).toBeDisabled();
    expect(screen.getByText("上一页")).not.toBeDisabled();
  });

  it("点击上一页/下一页触发 onPageChange", () => {
    const onPageChange = vi.fn();
    render(
      <Pagination
        page={2}
        pageSize={20}
        total={45}
        hasNext={true}
        onPageChange={onPageChange}
      />,
    );
    fireEvent.click(screen.getByText("上一页"));
    expect(onPageChange).toHaveBeenCalledWith(1);
    fireEvent.click(screen.getByText("下一页"));
    expect(onPageChange).toHaveBeenCalledWith(3);
  });

  it("total 为 0 时显示第 1/1 页", () => {
    render(
      <Pagination
        page={1}
        pageSize={20}
        total={0}
        hasNext={false}
        onPageChange={() => {}}
      />,
    );
    expect(screen.getByText(/第 1\/1 页/)).toBeInTheDocument();
  });
});
