/* eslint-disable indent */
import {takeEvery, takeLatest} from 'redux-saga/effects';
import * as serverAPI from '../api/server'; // api/auth 안의 함수 모두 불러오기
import {
    reducerUtils,
    handleAsyncActions,
    createPromiseSaga
} from '../lib/asyncUtils';

/* 액션 타입 */
const SET_SEARCH_SERVER_NAME = 'server/SET_SEARCH_SERVER_NAME';
const SET_SEARCH_SERVER_TYPE = 'server/SET_SEARCH_SERVER_TYPE';

const SEARCH_SERVER = 'server/SEARCH_SERVER'; // 요청 시작
const SEARCH_SERVER_SUCCESS = 'server/SEARCH_SERVER_SUCCESS'; // 요청 성공
const SEARCH_SERVER_ERROR = 'server/SEARCH_SERVER_ERROR'; // 요청 실패
const CLEAR_SEARCH_SERVER = 'server/CLEAR_SEARCH_SERVER'; // 조회 초기화

const CREATE_SERVER = 'server/CREATE_SERVER'; // 요청 시작
const CREATE_SERVER_SUCCESS = 'server/CREATE_SERVER_SUCCESS'; // 요청 성공
const CREATE_SERVER_ERROR = 'server/CREATE_SERVER_ERROR'; // 요청 실패
const CREATE_SERVER_DATA_CLEAR = 'server/CREATE_SERVER_DATA_CLEAR';

const SET_UPDATE_SERVER_INITDATA = 'server/SET_UPDATE_SERVER_INITDATA';
const USED_UPDATE_SERVER_INITDATA = 'server/USED_UPDATE_SERVER_INITDATA';

const UPDATE_SERVER = 'server/UPDATE_SERVER'; // 요청 시작
const UPDATE_SERVER_SUCCESS = 'server/UPDATE_SERVER_SUCCESS'; // 요청 성공
const UPDATE_SERVER_ERROR = 'server/UPDATE_SERVER_ERROR'; // 요청 실패
const UPDATE_SERVER_DATA_CLEAR = 'server/UPDATE_SERVER_DATA_CLEAR';

const DELETE_SERVER = 'server/DELETE_SERVER'; // 요청 시작
const DELETE_SERVER_SUCCESS = 'server/DELETE_SERVER_SUCCESS'; // 요청 성공
const DELETE_SERVER_ERROR = 'server/DELETE_SERVER_ERROR'; // 요청 실패
const DELETE_SERVER_DATA_CLEAR = 'server/DELETE_SERVER_DATA_CLEAR';

export const setSearchServerName = (serverName) => ({
    type: SET_SEARCH_SERVER_NAME,
    payload: {
        serverName
    }
});

export const setSearchServerType = (serverType) => ({
    type: SET_SEARCH_SERVER_TYPE,
    payload: {
        serverType
    }
});

export const searchServer = (serverName, serverType, page, size) => ({
    type: SEARCH_SERVER,
    payload: {
        serverName,
        serverType,
        page,
        size
    }
});

/*
 * 서버검색 초기화
 */
export const clearSearchServer = () => ({
    type: CLEAR_SEARCH_SERVER
});

export const createServer = (createData) => ({
    type: CREATE_SERVER,
    payload: {
        ...createData
    }
});

export const createServerDataClear = () => ({
    type: CREATE_SERVER_DATA_CLEAR
});

export const setUpdateServerInitData = (initData) => ({
    type: SET_UPDATE_SERVER_INITDATA,
    payload: {
        ...initData
    }
});

export const usedUpdateServerInitData = () => ({
    type: USED_UPDATE_SERVER_INITDATA
});

export const updateServer = (updateData) => ({
    type: UPDATE_SERVER,
    payload: {
        ...updateData
    }
});

export const updateServerDataClear = () => ({
    type: UPDATE_SERVER_DATA_CLEAR
});

export const deleteServer = (serverId) => ({
    type: DELETE_SERVER,
    payload: {
        serverId
    }
});

export const deleteServerDataClear = () => ({
    type: DELETE_SERVER_DATA_CLEAR
});

const searchServerSaga = createPromiseSaga(
    SEARCH_SERVER,
    serverAPI.searchServer
);

const createServerSaga = createPromiseSaga(
    CREATE_SERVER,
    serverAPI.createServer
);

const updateServerSaga = createPromiseSaga(
    UPDATE_SERVER,
    serverAPI.updateServer
);

const deleteServerSaga = createPromiseSaga(
    DELETE_SERVER,
    serverAPI.deleteServer
);

// 사가들을 합치기
export function* serverSaga() {
    yield takeLatest(SEARCH_SERVER, searchServerSaga);
    yield takeEvery(CREATE_SERVER, createServerSaga);
    yield takeEvery(UPDATE_SERVER, updateServerSaga);
    yield takeEvery(DELETE_SERVER, deleteServerSaga);
}

// initialState 쪽도 반복되는 코드를 initial() 함수를 사용해서 리팩토링 했습니다.
const initialState = {
    searchForm: {serverName: '', serverType: '', page: 1, size: 10},
    updateFormInitData: {
        useData: true
    },
    search: reducerUtils.initial(),
    create: reducerUtils.initial(),
    update: reducerUtils.initial(),
    delete: reducerUtils.initial()
};

export default function server(state = initialState, action) {
    switch (action.type) {
        case SET_SEARCH_SERVER_NAME:
            return {
                ...state,
                searchForm: {
                    ...state.searchForm,
                    serverName: action.payload.serverName
                }
            };
        case SET_SEARCH_SERVER_TYPE:
            return {
                ...state,
                searchForm: {
                    ...state.searchForm,
                    serverType: action.payload.serverType
                }
            };
        case SEARCH_SERVER:
        case SEARCH_SERVER_SUCCESS:
        case SEARCH_SERVER_ERROR:
            return handleAsyncActions(
                SEARCH_SERVER,
                'search',
                true
            )(state, action);

        case CLEAR_SEARCH_SERVER:
            return {
                ...state,
                search: reducerUtils.initial()
            };
        case CREATE_SERVER:
        case CREATE_SERVER_SUCCESS:
        case CREATE_SERVER_ERROR:
            return handleAsyncActions(
                CREATE_SERVER,
                'create',
                true
            )(state, action);
        case CREATE_SERVER_DATA_CLEAR:
            return {
                ...state,
                create: reducerUtils.initial()
            };
        case SET_UPDATE_SERVER_INITDATA:
            return {
                ...state,
                updateFormInitData: {
                    ...action.payload,
                    useData: false
                }
            };
        case USED_UPDATE_SERVER_INITDATA:
            return {
                ...state,
                updateFormInitData: {
                    ...state.updateFormInitData,
                    useData: true
                }
            };
        case UPDATE_SERVER:
        case UPDATE_SERVER_SUCCESS:
        case UPDATE_SERVER_ERROR:
            return handleAsyncActions(
                UPDATE_SERVER,
                'update',
                true
            )(state, action);
        case UPDATE_SERVER_DATA_CLEAR:
            return {
                ...state,
                update: reducerUtils.initial()
            };
        case DELETE_SERVER:
        case DELETE_SERVER_SUCCESS:
        case DELETE_SERVER_ERROR:
            return handleAsyncActions(
                DELETE_SERVER,
                'delete',
                true
            )(state, action);
        case DELETE_SERVER_DATA_CLEAR:
            return {
                ...state,
                delete: reducerUtils.initial()
            };
        default:
            return state;
    }
}
