import {mount} from '@vue/test-utils'
import {expect, it, describe} from 'vitest'
import RoutesList from "@organisms/RoutersEditor/index.vue"
import RouterRow from '@organisms/RoutersEditor/RouterRow.vue'
import routeOptions from '@store/modules/proxy/routeOptions.json'
import { deletedRoute } from '@store/modules/proxy/helpers'
import {createStore} from 'vuex'

const defaultRoutes = [{
  "id": 7,
  "created_at": "2024-02-27T12:02:34.666042252+03:00",
  "updated_at": "2024-02-27T12:02:34.666042252+03:00",
  "deleted_at": null,
  "server_id": -1,
  "path": "/route",
  "role": 0,
  "description": "with route",
  "order": 0,
  "deepness": 0,
  "is_cb_on": true,
  "cb_request_limit": 0,
  "cb_min_requests": 7,
  "cb_error_threshold_percentage": 0,
  "cb_interval_duration": 0,
  "cb_open_state_timeout": 0,
  "is_online": false
},
{
  "id": 8,
  "created_at": "2024-02-27T12:05:45.268921795+03:00",
  "updated_at": "2024-02-27T12:05:45.268921795+03:00",
  "deleted_at": null,
  "server_id": 7,
  "path": "new/3",
  "role": 0,
  "description": "",
  "order": 0,
  "deepness": 0,
  "is_cb_on": false,
  "cb_request_limit": 3,
  "cb_min_requests": 5,
  "cb_error_threshold_percentage": 0,
  "cb_interval_duration": 0,
  "cb_open_state_timeout": 0,
  "is_online": true
},
{
  "id": 9,
  "created_at": "2024-02-27T12:11:09.940033992+03:00",
  "updated_at": "2024-02-27T12:11:09.940033992+03:00",
  "deleted_at": null,
  "server_id": -1,
  "path": "new/1",
  "role": 0,
  "description": "",
  "order": 0,
  "deepness": 9,
  "is_cb_on": true,
  "cb_request_limit": 0,
  "cb_min_requests": 0,
  "cb_error_threshold_percentage": 0,
  "cb_interval_duration": 0,
  "cb_open_state_timeout": 5,
  "is_online": false
}]

const store = createStore({
  plugins: [],
  modules: {
    proxy: {
      state: {
        routes: [],
        routesState: "await",
        routesLib: {},
        routeOptions: routeOptions
      },
      getters: {
        routes: (state) => state.routes,
        routesState: (state) => state.routesState,
        routesLib:   (state) => state.routes.reduce((acc, cur) => ({
          ...acc,
          [cur.id]: cur
        }), {}),
        routeOptions: (state) => state.routeOptions,
      },
      mutations: {
        setRoutes: (state, updval) =>  state.routes = updval,
        setRoutesState: (state, updval) => state.routesState = updval,
        setRoutesLib: (state, updval) => state.routesLib = updval,
      },
      actions: {
        uploadSiteRoutes: async ({commit}, siteProps) => {
          commit('setSelectedSite', siteProps)
          commit('setRoutes', defaultRoutes)
        },
        updateRouteRow: () => ({}),
        removeRoute: ({commit, state}, id) => {
          const updatedRoutes = deletedRoute(id, state.routes)
          commit('setRoutes', updatedRoutes)
        },
        breateAddingRoute: () => ({}),
      },
      namespaced: true,
    }
  }
})

describe("Routes", () => {
  
  it("Not renders routes and buttons in RoutesList, if routesState value not 'active'", async () => {

    const wrapper = mount(RoutesList, {
      global: {
        plugins: [store],
      },
      shallow: true,
    })
    
    expect(wrapper.html()).not.toContain('Добавить роут')
    expect(wrapper.html()).not.toContain('Закрыть')
  })

  it("Not renders routes - empty array in RoutesList, if routesState value 'active', renders buttons", async () => {

    store.commit('proxy/setRoutesState', 'active')

    const getters = {...store.getters }
    const routesState = getters['proxy/routesState']

    const wrapper = mount(RoutesList, {
      global: {
        plugins: [store],
      },
      data() {
        return {
          open: false,
        }
      },
    })

    if (routesState === 'active') {
      await wrapper.setData({ open: true })
    }
    
    expect(wrapper.html()).toContain('Добавить роут')
    expect(wrapper.html()).toContain('Закрыть')
    expect(wrapper.html()).not.toContain('ri-delete-bin-line')
  })

  it("Renders route in RoutesList, if routesState value 'active' and default props", async () => {

    const wrapper = mount(RouterRow, {
      global: {
        plugins: [store],
      },
    })
    
    expect(wrapper.html()).toContain('ri-delete-bin-line')
  })

  it("Renders route in RoutesList, with set props", async () => {

    const wrapper = mount(RouterRow, {
      global: {
        plugins: [store],
        stubs: ['Input', 'Textarea', 'DoubleSwitch'],
      },
      props: {
        id:  1,
        path: "/route1",
        description: "default",
        minRequests: 3,
      },
    })

    expect(wrapper.html()).toContain('/route1') // default props
    expect(wrapper.html()).toContain('/route1') // default props
    expect(wrapper.html()).toContain('3') // default props

    await wrapper.setProps({ path: '/route2', minRequests: 7, description: 'test route' })
    
    expect(wrapper.html()).toContain('ri-delete-bin-line')
    expect(wrapper.html()).toContain('test route') // updated props
    expect(wrapper.html()).toContain('/route2') // updated props
    expect(wrapper.html()).toContain('7') // updated props
  })

  it("Renders buttons delete and cancel in route, after click button delete", async () => {

    const wrapper = mount(RouterRow, {
      global: {
        plugins: [store],
        stubs: ['Input', 'Textarea', 'DoubleSwitch'],
      },
    })

    await wrapper.get('.ri-delete-bin-line').trigger('click')
    
    expect(wrapper.html()).not.toContain('ri-delete-bin-line')
    expect(wrapper.html()).toContain('Отменить')
    expect(wrapper.html()).toContain('Удалить')
  })

  it("Renders default route state, after click button delete and click button cancel", async () => {

    const wrapper = mount(RouterRow, {
      global: {
        plugins: [store],
        stubs: ['Input', 'Textarea', 'DoubleSwitch'],
      },
    })

    await wrapper.get('.ri-delete-bin-line').trigger('click')
    await wrapper.get('.bg-gray-700').trigger('click')

    // console.log('wrapper 6 test', wrapper.html())
    
    expect(wrapper.html()).toContain('ri-delete-bin-line')
    expect(wrapper.html()).not.toContain('Отменить')
    expect(wrapper.html()).not.toContain('Удалить')
  })

})


