import { describe, it, expect, vi, beforeEach } from "vitest";
import { render, screen, fireEvent, waitFor } from "@testing-library/react";
import BlindboxPlan from "./BlindboxPlan";
import type { WeekendPlanData } from "@/types";

beforeEach(() => {
  Element.prototype.scrollTo = vi.fn();
});

vi.mock("@/components/BlindboxMyIdeas", () => ({
  CategoryBadge: ({ category }: { category: string }) => (
    <span data-testid="category-badge">{category}</span>
  ),
}));

const mockDays: WeekendPlanData[] = [
  {
    date: "周六",
    summary: "轻松的一天",
    items: [
      {
        time: "10:00",
        activity: "去公园散步",
        poi: "朝阳公园",
        address: "朝阳区",
        duration: 120,
        lat: 39.9,
        lng: 116.4,
        reason: "空气好",
      },
      {
        time: "14:00",
        activity: "午餐",
        poi: "海底捞",
        address: "朝阳区",
        duration: 90,
        lat: 39.9,
        lng: 116.4,
      },
    ],
  },
  {
    date: "周日",
    summary: "文艺的一天",
    items: [
      {
        time: "10:00",
        activity: "参观博物馆",
        poi: "国家博物馆",
        address: "东城区",
        duration: 180,
        lat: 39.9,
        lng: 116.4,
      },
    ],
  },
];

const mockOnAccept = vi.fn();
const mockOnRegenerate = vi.fn();
const mockOnShare = vi.fn();
const mockOnBack = vi.fn();

function renderPlan(overrides = {}) {
  return render(
    <BlindboxPlan
      days={mockDays}
      onAccept={mockOnAccept}
      onRegenerate={mockOnRegenerate}
      onShare={mockOnShare}
      onBack={mockOnBack}
      {...overrides}
    />,
  );
}

describe("BlindboxPlan", () => {
  it("renders day header with date", () => {
    renderPlan();
    expect(screen.getByText(/周六 · 行程规划/)).toBeInTheDocument();
  });

  it("renders summary text", () => {
    renderPlan();
    expect(screen.getByText("轻松的一天")).toBeInTheDocument();
  });

  it("renders timeline items", () => {
    renderPlan();
    expect(screen.getByText("去公园散步")).toBeInTheDocument();
    expect(screen.getByText("朝阳公园")).toBeInTheDocument();
    expect(screen.getByText("午餐")).toBeInTheDocument();
  });

  it("shows duration formatted", () => {
    renderPlan();
    expect(screen.getByText("2h")).toBeInTheDocument();
    expect(screen.getByText("1h30min")).toBeInTheDocument();
  });

  it("shows accept and regenerate buttons when not accepted", () => {
    renderPlan();
    expect(screen.getByText("接受契约")).toBeInTheDocument();
    expect(screen.getByText("换一个方案")).toBeInTheDocument();
  });

  it("shows share button when accepted", () => {
    renderPlan({ accepted: true });
    expect(screen.getByText("分享计划")).toBeInTheDocument();
    expect(screen.queryByText("接受契约")).not.toBeInTheDocument();
  });

  it("calls onAccept", () => {
    renderPlan();
    fireEvent.click(screen.getByText("接受契约"));
    expect(mockOnAccept).toHaveBeenCalled();
  });

  it("calls onRegenerate", () => {
    renderPlan();
    fireEvent.click(screen.getByText("换一个方案"));
    expect(mockOnRegenerate).toHaveBeenCalled();
  });

  it("calls onBack", () => {
    renderPlan();
    fireEvent.click(screen.getByText("返回想法池"));
    expect(mockOnBack).toHaveBeenCalled();
  });

  it("navigates between days", async () => {
    renderPlan();
    expect(screen.getByText(/周六 · 行程规划/)).toBeInTheDocument();

    fireEvent.click(screen.getByText("周日"));
    await waitFor(() => {
      expect(screen.getByText(/周日 · 行程规划/)).toBeInTheDocument();
    });
  });

  it("shows day indicators for multi-day plans", () => {
    renderPlan();
    expect(screen.getByText("1 / 2")).toBeInTheDocument();
  });

  it("shows navigation link for items with coordinates", () => {
    renderPlan();
    const navLinks = screen.getAllByText("导航");
    expect(navLinks.length).toBeGreaterThan(0);
  });

  it("shows reason when available", () => {
    renderPlan();
    expect(screen.getByText("空气好")).toBeInTheDocument();
  });
});
