import { mount } from "@vue/test-utils";
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
import CallPage from "@/components/call/CallPage.vue";

describe("CallPage.vue", () => {
    let axiosMock;

    beforeEach(() => {
        axiosMock = {
            get: vi.fn().mockImplementation((url) => {
                const defaultData = {
                    config: {},
                    calls: [],
                    call_history: [],
                    announces: [],
                    voicemails: [],
                    active_call: null,
                    discovery: [],
                    contacts: [],
                    profiles: [],
                    ringtones: [],
                    voicemail: { unread_count: 0 },
                };

                if (url.includes("/api/v1/config")) return Promise.resolve({ data: { config: {} } });
                if (url.includes("/api/v1/telephone/history")) return Promise.resolve({ data: { call_history: [] } });
                if (url.includes("/api/v1/announces")) return Promise.resolve({ data: { announces: [] } });
                if (url.includes("/api/v1/telephone/status")) return Promise.resolve({ data: { active_call: null } });
                if (url.includes("/api/v1/telephone/voicemail/status"))
                    return Promise.resolve({ data: { has_espeak: false } });
                if (url.includes("/api/v1/telephone/ringtones/status"))
                    return Promise.resolve({ data: { enabled: true } });
                if (url.includes("/api/v1/telephone/ringtones")) return Promise.resolve({ data: { ringtones: [] } });
                if (url.includes("/api/v1/telephone/audio-profiles"))
                    return Promise.resolve({ data: { audio_profiles: [], default_audio_profile_id: null } });
                if (url.includes("/api/v1/contacts")) return Promise.resolve({ data: { contacts: [] } });

                return Promise.resolve({ data: defaultData });
            }),
            post: vi.fn().mockResolvedValue({ data: {} }),
            patch: vi.fn().mockResolvedValue({ data: {} }),
            delete: vi.fn().mockResolvedValue({ data: {} }),
        };
        window.axios = axiosMock;
    });

    afterEach(() => {
        delete window.axios;
    });

    const mountCallPage = () => {
        return mount(CallPage, {
            global: {
                mocks: {
                    $t: (key) => key,
                },
                stubs: {
                    MaterialDesignIcon: true,
                    LoadingSpinner: true,
                    LxmfUserIcon: true,
                },
            },
        });
    };

    it("renders tabs correctly", async () => {
        const wrapper = mountCallPage();
        await wrapper.vm.$nextTick();

        // The tabs are hardcoded strings: Phone, Phonebook, Voicemail, Contacts
        expect(wrapper.text()).toContain("Phone");
        expect(wrapper.text()).toContain("Phonebook");
        expect(wrapper.text()).toContain("Voicemail");
        expect(wrapper.text()).toContain("Contacts");
    });

    it("switches tabs when clicked", async () => {
        const wrapper = mountCallPage();
        await wrapper.vm.$nextTick();

        // Initial tab should be phone
        expect(wrapper.vm.activeTab).toBe("phone");

        // Click Phonebook tab
        const buttons = wrapper.findAll("button");
        const phonebookTab = buttons.find((b) => b.text() === "Phonebook");
        if (phonebookTab) {
            await phonebookTab.trigger("click");
            expect(wrapper.vm.activeTab).toBe("phonebook");
        } else {
            throw new Error("Phonebook tab not found");
        }
    });

    it("displays 'New Call' UI by default when no active call", async () => {
        const wrapper = mountCallPage();
        await wrapper.vm.$nextTick();

        expect(wrapper.text()).toContain("New Call");
        expect(wrapper.find('input[type="text"]').exists()).toBe(true);
    });

    it("attempts to place a call when 'Call' button is clicked", async () => {
        const wrapper = mountCallPage();
        await wrapper.vm.$nextTick();

        const input = wrapper.find('input[type="text"]');
        await input.setValue("test-destination");

        // Find Call button - it's hardcoded "Call"
        const buttons = wrapper.findAll("button");
        const callButton = buttons.find((b) => b.text() === "Call");
        if (callButton) {
            await callButton.trigger("click");
            // CallPage.vue uses window.axios.get(`/api/v1/telephone/call/${hashToCall}`)
            expect(axiosMock.get).toHaveBeenCalledWith(
                expect.stringContaining("/api/v1/telephone/call/test-destination")
            );
        } else {
            throw new Error("Call button not found");
        }
    });
});
