import { describe, it, expect, beforeEach } from "vitest";
import { mount } from "@vue/test-utils";
import { createPinia, setActivePinia } from "pinia";
import RunnerCard from "~/components/Game/RunnerCard.vue";
import { useGameStore } from "~/store/game";
import type { LineupPlayerState } from "~/types/game";

describe("RunnerCard", () => {
    let pinia: ReturnType<typeof createPinia>;

    beforeEach(() => {
        pinia = createPinia();
        setActivePinia(pinia);
    });

    const mockRunner: LineupPlayerState = {
        lineup_id: 1,
        batting_order: 1,
        position: "LF",
        card_id: 101,
    };

    describe("empty base state", () => {
        it("renders empty state when no runner provided", () => {
            const wrapper = mount(RunnerCard, {
                global: { plugins: [pinia] },
                props: {
                    base: "1B",
                    runner: null,
                    isExpanded: false,
                    teamColor: "#3b82f6",
                },
            });

            expect(wrapper.find(".runner-card.empty").exists()).toBe(true);
            expect(wrapper.text()).toContain("Empty");
        });

        it("displays base label for empty base", () => {
            const wrapper = mount(RunnerCard, {
                global: { plugins: [pinia] },
                props: {
                    base: "2B",
                    runner: null,
                    isExpanded: false,
                    teamColor: "#3b82f6",
                },
            });

            expect(wrapper.text()).toContain("2B");
        });

        it("shows hollow circle for empty base", () => {
            const wrapper = mount(RunnerCard, {
                global: { plugins: [pinia] },
                props: {
                    base: "3B",
                    runner: null,
                    isExpanded: false,
                    teamColor: "#3b82f6",
                },
            });

            const circle = wrapper.find(".rounded-full.border-dashed");
            expect(circle.exists()).toBe(true);
        });

        it("does not emit click event for empty base", async () => {
            const wrapper = mount(RunnerCard, {
                global: { plugins: [pinia] },
                props: {
                    base: "1B",
                    runner: null,
                    isExpanded: false,
                    teamColor: "#3b82f6",
                },
            });

            await wrapper.trigger("click");
            expect(wrapper.emitted("click")).toBeUndefined();
        });
    });

    describe("occupied base state", () => {
        beforeEach(() => {
            const gameStore = useGameStore();
            // Set game state first so updateLineup knows the team ID
            gameStore.setGameState({
                id: 1,
                home_team_id: 1,
                away_team_id: 2,
                status: "active",
                inning: 1,
                half: "top",
                outs: 0,
                home_score: 0,
                away_score: 0,
                home_team_abbrev: "NYY",
                away_team_abbrev: "BOS",
                home_team_dice_color: "3b82f6",
                current_batter: null,
                current_pitcher: null,
                on_first: null,
                on_second: null,
                on_third: null,
                decision_phase: "idle",
                play_count: 0,
            });

            gameStore.updateLineup(1, [
                {
                    id: 1,
                    lineup_id: 1,
                    team_id: 1,
                    batting_order: 1,
                    position: "LF",
                    is_active: true,
                    player: {
                        id: 101,
                        name: "Mike Trout",
                        image: "https://example.com/trout.jpg",
                        headshot: "https://example.com/trout-headshot.jpg",
                    },
                },
            ]);
        });

        it("renders occupied state when runner provided", () => {
            const wrapper = mount(RunnerCard, {
                global: { plugins: [pinia] },
                props: {
                    base: "1B",
                    runner: mockRunner,
                    isExpanded: false,
                    teamColor: "#3b82f6",
                },
            });

            expect(wrapper.find(".runner-card.occupied").exists()).toBe(true);
            expect(wrapper.find(".runner-card.empty").exists()).toBe(false);
        });

        it("displays runner name", () => {
            const wrapper = mount(RunnerCard, {
                global: { plugins: [pinia] },
                props: {
                    base: "1B",
                    runner: mockRunner,
                    isExpanded: false,
                    teamColor: "#3b82f6",
                },
            });

            expect(wrapper.text()).toContain("Mike Trout");
        });

        it("displays base label", () => {
            const wrapper = mount(RunnerCard, {
                global: { plugins: [pinia] },
                props: {
                    base: "2B",
                    runner: mockRunner,
                    isExpanded: false,
                    teamColor: "#3b82f6",
                },
            });

            expect(wrapper.text()).toContain("2B");
        });

        it("displays runner number based on lineup_id", () => {
            const wrapper = mount(RunnerCard, {
                global: { plugins: [pinia] },
                props: {
                    base: "1B",
                    runner: mockRunner,
                    isExpanded: false,
                    teamColor: "#3b82f6",
                },
            });

            expect(wrapper.text()).toContain("#01");
        });

        it("displays player headshot when available", () => {
            const wrapper = mount(RunnerCard, {
                global: { plugins: [pinia] },
                props: {
                    base: "1B",
                    runner: mockRunner,
                    isExpanded: false,
                    teamColor: "#3b82f6",
                },
            });

            const img = wrapper.find('img[alt="Mike Trout"]');
            expect(img.exists()).toBe(true);
            expect(img.attributes("src")).toBe(
                "https://example.com/trout-headshot.jpg",
            );
        });

        it("applies team color to border", () => {
            const wrapper = mount(RunnerCard, {
                global: { plugins: [pinia] },
                props: {
                    base: "1B",
                    runner: mockRunner,
                    isExpanded: false,
                    teamColor: "#ff0000",
                },
            });

            const avatar = wrapper.find(".rounded-full.border-2");
            expect(avatar.attributes("style")).toContain(
                "border-color: #ff0000",
            );
        });

        it("shows chevron icon when occupied", () => {
            const wrapper = mount(RunnerCard, {
                global: { plugins: [pinia] },
                props: {
                    base: "1B",
                    runner: mockRunner,
                    isExpanded: false,
                    teamColor: "#3b82f6",
                },
            });

            const chevron = wrapper.find("svg");
            expect(chevron.exists()).toBe(true);
        });

        it("emits click event when clicked", async () => {
            const wrapper = mount(RunnerCard, {
                global: { plugins: [pinia] },
                props: {
                    base: "1B",
                    runner: mockRunner,
                    isExpanded: false,
                    teamColor: "#3b82f6",
                },
            });

            await wrapper.trigger("click");
            expect(wrapper.emitted("click")).toHaveLength(1);
        });
    });

    describe("expanded state", () => {
        beforeEach(() => {
            const gameStore = useGameStore();
            gameStore.setGameState({
                id: 1,
                home_team_id: 1,
                away_team_id: 2,
                status: "active",
                inning: 1,
                half: "top",
                outs: 0,
                on_base_code: 0,
                home_team: {
                    id: 1,
                    name: "Home Team",
                    abbreviation: "HOME",
                    dice_color: "3b82f6",
                },
                away_team: {
                    id: 2,
                    name: "Away Team",
                    abbreviation: "AWAY",
                    dice_color: "10b981",
                },
            });
            gameStore.updateLineup(1, [
                {
                    id: 1,
                    lineup_id: 1,
                    team_id: 1,
                    batting_order: 1,
                    position: "LF",
                    is_active: true,
                    player: {
                        id: 101,
                        name: "Mike Trout",
                        image: "https://example.com/trout-card.jpg",
                        headshot: "https://example.com/trout-headshot.jpg",
                    },
                },
            ]);
        });

        it("does not show expanded view when collapsed", () => {
            const wrapper = mount(RunnerCard, {
                global: { plugins: [pinia] },
                props: {
                    base: "1B",
                    runner: mockRunner,
                    isExpanded: false,
                    teamColor: "#3b82f6",
                },
            });

            expect(wrapper.find(".runner-expanded").exists()).toBe(false);
        });

        it("shows expanded view when isExpanded is true", () => {
            const wrapper = mount(RunnerCard, {
                global: { plugins: [pinia] },
                props: {
                    base: "1B",
                    runner: mockRunner,
                    isExpanded: true,
                    teamColor: "#3b82f6",
                },
            });

            expect(wrapper.find(".runner-expanded").exists()).toBe(true);
        });

        it("displays full player card image when expanded", () => {
            const wrapper = mount(RunnerCard, {
                global: { plugins: [pinia] },
                props: {
                    base: "1B",
                    runner: mockRunner,
                    isExpanded: true,
                    teamColor: "#3b82f6",
                },
            });

            const cardImg = wrapper.find(
                '.runner-expanded img[alt="Mike Trout card"]',
            );
            expect(cardImg.exists()).toBe(true);
            expect(cardImg.attributes("src")).toBe(
                "https://example.com/trout-card.jpg",
            );
        });

        it("shows player initials when no card image available", () => {
            const gameStore = useGameStore();
            gameStore.setGameState({
                id: 1,
                home_team_id: 1,
                away_team_id: 2,
                status: "active",
                inning: 1,
                half: "top",
                outs: 0,
                on_base_code: 0,
                home_team: {
                    id: 1,
                    name: "Home Team",
                    abbreviation: "HOME",
                    dice_color: "3b82f6",
                },
                away_team: {
                    id: 2,
                    name: "Away Team",
                    abbreviation: "AWAY",
                    dice_color: "10b981",
                },
            });
            gameStore.updateLineup(1, [
                {
                    id: 1,
                    lineup_id: 1,
                    team_id: 1,
                    batting_order: 1,
                    position: "LF",
                    is_active: true,
                    player: {
                        id: 101,
                        name: "Mike Trout",
                        image: "",
                        headshot: "",
                    },
                },
            ]);

            const wrapper = mount(RunnerCard, {
                global: { plugins: [pinia] },
                props: {
                    base: "1B",
                    runner: mockRunner,
                    isExpanded: true,
                    teamColor: "#3b82f6",
                },
            });

            expect(wrapper.text()).toContain("MT");
        });

        it('displays "RUNNER" label in expanded header', () => {
            const wrapper = mount(RunnerCard, {
                global: { plugins: [pinia] },
                props: {
                    base: "2B",
                    runner: mockRunner,
                    isExpanded: true,
                    teamColor: "#3b82f6",
                },
            });

            expect(wrapper.find(".runner-expanded").text()).toContain("RUNNER");
        });

        it("applies expanded class when isExpanded is true", () => {
            const wrapper = mount(RunnerCard, {
                global: { plugins: [pinia] },
                props: {
                    base: "1B",
                    runner: mockRunner,
                    isExpanded: true,
                    teamColor: "#3b82f6",
                },
            });

            expect(wrapper.find(".runner-card.expanded").exists()).toBe(true);
        });

        it("rotates chevron when expanded", () => {
            const wrapper = mount(RunnerCard, {
                global: { plugins: [pinia] },
                props: {
                    base: "1B",
                    runner: mockRunner,
                    isExpanded: true,
                    teamColor: "#3b82f6",
                },
            });

            const chevron = wrapper.find("svg");
            expect(chevron.classes()).toContain("rotate-90");
        });
    });

    describe("player name handling", () => {
        it('shows "Unknown Runner" when player not found in store', () => {
            const wrapper = mount(RunnerCard, {
                global: { plugins: [pinia] },
                props: {
                    base: "1B",
                    runner: mockRunner,
                    isExpanded: false,
                    teamColor: "#3b82f6",
                },
            });

            expect(wrapper.text()).toContain("Unknown Runner");
        });

        it("extracts initials from first and last name", () => {
            const gameStore = useGameStore();
            gameStore.setGameState({
                id: 1,
                home_team_id: 1,
                away_team_id: 2,
                status: "active",
                inning: 1,
                half: "top",
                outs: 0,
                on_base_code: 0,
                home_team: {
                    id: 1,
                    name: "Home Team",
                    abbreviation: "HOME",
                    dice_color: "3b82f6",
                },
                away_team: {
                    id: 2,
                    name: "Away Team",
                    abbreviation: "AWAY",
                    dice_color: "10b981",
                },
            });
            gameStore.updateLineup(1, [
                {
                    id: 1,
                    lineup_id: 1,
                    team_id: 1,
                    batting_order: 1,
                    position: "LF",
                    is_active: true,
                    player: {
                        id: 101,
                        name: "Aaron Donald Judge",
                        image: "",
                    },
                },
            ]);

            const wrapper = mount(RunnerCard, {
                global: { plugins: [pinia] },
                props: {
                    base: "1B",
                    runner: mockRunner,
                    isExpanded: true,
                    teamColor: "#3b82f6",
                },
            });

            // Should use first and last name (A + J)
            expect(wrapper.text()).toContain("AJ");
        });

        it("handles single-word names", () => {
            const gameStore = useGameStore();
            gameStore.setGameState({
                id: 1,
                home_team_id: 1,
                away_team_id: 2,
                status: "active",
                inning: 1,
                half: "top",
                outs: 0,
                on_base_code: 0,
                home_team: {
                    id: 1,
                    name: "Home Team",
                    abbreviation: "HOME",
                    dice_color: "3b82f6",
                },
                away_team: {
                    id: 2,
                    name: "Away Team",
                    abbreviation: "AWAY",
                    dice_color: "10b981",
                },
            });
            gameStore.updateLineup(1, [
                {
                    id: 1,
                    lineup_id: 1,
                    team_id: 1,
                    batting_order: 1,
                    position: "LF",
                    is_active: true,
                    player: {
                        id: 101,
                        name: "Pele",
                        image: "",
                    },
                },
            ]);

            const wrapper = mount(RunnerCard, {
                global: { plugins: [pinia] },
                props: {
                    base: "1B",
                    runner: mockRunner,
                    isExpanded: true,
                    teamColor: "#3b82f6",
                },
            });

            expect(wrapper.text()).toContain("PE");
        });
    });

    describe("base label variations", () => {
        it("displays 1B correctly", () => {
            const wrapper = mount(RunnerCard, {
                global: { plugins: [pinia] },
                props: {
                    base: "1B",
                    runner: null,
                    isExpanded: false,
                    teamColor: "#3b82f6",
                },
            });

            expect(wrapper.text()).toContain("1B");
        });

        it("displays 2B correctly", () => {
            const wrapper = mount(RunnerCard, {
                global: { plugins: [pinia] },
                props: {
                    base: "2B",
                    runner: null,
                    isExpanded: false,
                    teamColor: "#3b82f6",
                },
            });

            expect(wrapper.text()).toContain("2B");
        });

        it("displays 3B correctly", () => {
            const wrapper = mount(RunnerCard, {
                global: { plugins: [pinia] },
                props: {
                    base: "3B",
                    runner: null,
                    isExpanded: false,
                    teamColor: "#3b82f6",
                },
            });

            expect(wrapper.text()).toContain("3B");
        });
    });
});
