"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __setModuleDefault(result, mod);
    return result;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
Object.defineProperty(exports, "__esModule", { value: true });
const antd_1 = require("antd");
const effects_1 = require("redux-saga/effects");
const typesafe_actions_1 = require("typesafe-actions");
const ACTIONS = __importStar(require("@/actions/builder/main"));
const common_1 = require("@/apis/application/common");
const API = __importStar(require("@/apis/builder/content"));
const page_1 = require("@/apis/builder/page");
const project_1 = require("@/apis/project");
const index_1 = require("@/foxI18n/index");
const index_2 = require("@/store/index");
const services_1 = require("./services");
const utils_1 = require("./utils");
function* handleFetchApp(action) {
    yield (0, effects_1.put)(ACTIONS.updateLoading(true));
    const { id } = action.payload;
    const res = yield (0, effects_1.call)(common_1.fetchAppDetail, {
        applicationId: id,
    });
    if (res.code === 200) {
        yield (0, effects_1.put)(ACTIONS.pushApp(res.data));
    }
    else {
        const { global: { fetchListFailed }, } = (0, index_1.getBusinessI18n)();
        antd_1.message.error(fetchListFailed);
    }
    // yield put(ACTIONS.updateLoading(false));
}
function* handleFetchFile(action) {
    yield (0, effects_1.put)(ACTIONS.updateLoading(true));
    const { applicationId, ids = [] } = action.payload;
    const res = yield (0, effects_1.call)(project_1.fetchFileDetail, {
        applicationId,
        ids,
    });
    if (res.code === 200) {
        yield (0, effects_1.put)(ACTIONS.pushFile(res.data));
    }
    else {
        const { global: { fetchListFailed }, } = (0, index_1.getBusinessI18n)();
        antd_1.message.error(fetchListFailed);
    }
    // yield put(ACTIONS.updateLoading(false));
}
function* handleFetchLiveContent(action) {
    const { params } = action.payload;
    const res = yield (0, effects_1.call)(API.fetchPageLiveVersion, Object.assign({}, params));
    if (res.code === 200) {
    }
    else {
        const { global: { fetchListFailed }, } = (0, index_1.getBusinessI18n)();
        antd_1.message.error(fetchListFailed);
        return null;
    }
}
function afterFetch(data) {
    var _a, _b, _c, _d, _e;
    return __awaiter(this, void 0, void 0, function* () {
        if (!data) {
            return null;
        }
        const application = index_2.store.getState().builder.main.application;
        if (!application) {
            return null;
        }
        // get extend content
        let extend;
        const { extendId } = ((_a = data.content) === null || _a === void 0 ? void 0 : _a.extension) || {};
        if (extendId) {
            const result = (yield API.fetchPageLiveVersion({
                applicationId: application.id,
                id: extendId,
            }));
            if (result.code === 200) {
                extend = result.data;
            }
        }
        let pageContent = data;
        // TODO: need to clean
        let pageNode = (_c = (_b = data === null || data === void 0 ? void 0 : data.content) === null || _b === void 0 ? void 0 : _b.schemas) === null || _c === void 0 ? void 0 : _c.find((item) => item.name === 'page' || item.name === '');
        if (!pageNode) {
            pageNode = (_e = (_d = extend === null || extend === void 0 ? void 0 : extend.content) === null || _d === void 0 ? void 0 : _d.schemas) === null || _e === void 0 ? void 0 : _e.find((item) => item.name === 'page' || item.name === '');
            if (pageNode) {
                pageNode = Object.assign(Object.assign({}, pageNode), { id: (0, utils_1.generateStructureId)(), children: [], extension: { extendId: pageNode.id } });
                pageContent = Object.assign(Object.assign({}, data), { content: Object.assign(Object.assign({}, data.content), { schemas: [...data.content.schemas, pageNode] }) });
            }
        }
        // init state
        const state = yield (0, services_1.initState)(pageContent, {
            application,
            locale: index_2.store.getState().builder.header.locale,
            components: index_2.store.getState().builder.component.components,
            extendPage: extend,
            file: index_2.store.getState().builder.main.file,
        });
        return { state, extend };
    });
}
function* handleFetchContent(action) {
    yield (0, effects_1.put)(ACTIONS.updateLoading(true));
    const { applicationId, id, type = 'page' } = action.payload;
    const isPage = type === 'page';
    const res = yield (0, effects_1.call)(isPage ? API.fetchPageBuildVersion : API.fetchTemplateBuildVersion, {
        applicationId,
        id,
    });
    if (res.code === 200) {
        // backup
        yield (0, effects_1.put)(ACTIONS.pushContent(res.data));
        // init state
        const { state, extend } = yield (0, effects_1.call)(afterFetch, Object.assign({}, res.data));
        // TODO: need to clean
        const pageNode = Object.values(state.originPageNodeMap).find((item) => item.name === 'page' || item.name === '');
        if (pageNode) {
            pageNode.name = 'page';
        }
        yield (0, effects_1.put)(ACTIONS.pushPageNode(pageNode || null));
        yield (0, effects_1.put)(ACTIONS.pushLiveContent(extend));
        yield (0, effects_1.put)(ACTIONS.pushFormatData(state));
    }
    else {
        const { global: { fetchListFailed }, } = (0, index_1.getBusinessI18n)();
        antd_1.message.error(fetchListFailed);
    }
    yield (0, effects_1.put)(ACTIONS.updateLoading(false));
}
function* handleSaveContent() {
    yield (0, effects_1.put)(ACTIONS.updateSaveLoading(true));
    yield (0, effects_1.delay)(100);
    const { application, file, pageContent, localVariables, pageNode } = index_2.store.getState().builder.main;
    const appId = (application === null || application === void 0 ? void 0 : application.id) || '';
    const relations = Object.assign(Object.assign({}, pageContent.relations), { variables: (pageContent.relations.variables || []).concat(localVariables) });
    // get the need save content, filter props
    const needSaved = (0, utils_1.getSaveContent)(pageContent, { pageNode });
    const validate = (0, services_1.validateContent)(needSaved, { relations });
    if (!validate) {
        yield (0, effects_1.put)(ACTIONS.updateSaveLoading(false));
        return null;
    }
    const res = yield (0, effects_1.call)(file.type === 'page' ? API.savePageContent : API.saveTemplateContent, {
        applicationId: appId,
        id: needSaved.content.id,
        content: needSaved.content,
    });
    const { global: { saveFailed, saveSuccess }, } = (0, index_1.getBusinessI18n)();
    if (res.code === 200) {
        antd_1.message.success(saveSuccess);
        yield (0, effects_1.put)(ACTIONS.updateEditState(false));
        yield (0, effects_1.put)(ACTIONS.fetchContent({ applicationId: appId, id: needSaved.content.id, type: file.type || 'page' }));
    }
    else {
        antd_1.message.error(saveFailed);
        return null;
    }
    yield (0, effects_1.put)(ACTIONS.updateSaveLoading(false));
}
function* handlePublishContent() {
    yield (0, effects_1.put)(ACTIONS.updatePublishing(true));
    const { application, file, pageContent, content, editStatus = false } = index_2.store.getState().builder.main;
    const appId = application === null || application === void 0 ? void 0 : application.id;
    if (editStatus) {
        yield (0, effects_1.put)(ACTIONS.saveContent());
    }
    // recheck saved
    const { global: { publishFailed, publishSuccess }, builder: { saveTips }, } = (0, index_1.getBusinessI18n)();
    const reCheck = index_2.store.getState().builder.main.editStatus;
    if (reCheck) {
        antd_1.message.warn(saveTips);
        return;
    }
    const res = yield (0, effects_1.call)(file.type === 'page' ? API.publishPage : API.publishTemplate, {
        applicationId: appId,
        id: pageContent.id,
        status: 'release',
    });
    if (res.code === 200) {
        // yield put(ACTIONS.pushContent(res.data));
        antd_1.message.success(publishSuccess);
        yield (0, effects_1.put)(ACTIONS.fetchContent({ applicationId: appId || '', id: content.id, type: file.type || 'page' }));
    }
    else {
        antd_1.message.error(publishFailed);
    }
    yield (0, effects_1.put)(ACTIONS.updatePublishing(false));
}
function* handleCloneContent(actions) {
    const { contentId } = actions.payload;
    const { global: { cloneSuccess, cloneFailed }, } = (0, index_1.getBusinessI18n)();
    const { application, content, file } = index_2.store.getState().builder.main;
    const appId = (application === null || application === void 0 ? void 0 : application.id) || '';
    if (!appId) {
        return;
    }
    const res = yield (0, effects_1.call)(page_1.clonePage, {
        applicationId: appId,
        targetContentId: content.id,
        sourceContentId: contentId,
    });
    if (res.code === 200) {
        antd_1.message.success(cloneSuccess);
        yield (0, effects_1.put)(ACTIONS.fetchContent({ applicationId: appId, id: content.id, type: file.type || 'page' }));
    }
    else {
        antd_1.message.error(cloneFailed);
    }
}
// TODO: need to clean
function* handlePageNodeChange(actions) {
    const { data } = actions.payload;
    const { application, content, file } = index_2.store.getState().builder.main;
    if (application && application.id && content && content.id) {
        const { tpl: newTpl = '' } = data.directive || {};
        if (newTpl) {
            // save first
            yield (0, effects_1.put)(ACTIONS.saveContent());
            yield (0, effects_1.delay)(200);
            yield (0, effects_1.put)(ACTIONS.fetchContent({
                applicationId: application.id || '',
                id: content.id,
                type: file.type || 'page',
            }));
        }
    }
    yield (0, effects_1.put)(ACTIONS.pushPageNode(data));
}
function* watch() {
    yield (0, effects_1.takeLatest)((0, typesafe_actions_1.getType)(ACTIONS.fetchApp), handleFetchApp);
    yield (0, effects_1.takeLatest)((0, typesafe_actions_1.getType)(ACTIONS.fetchFile), handleFetchFile);
    yield (0, effects_1.takeLatest)((0, typesafe_actions_1.getType)(ACTIONS.fetchContent), handleFetchContent);
    yield (0, effects_1.takeLatest)((0, typesafe_actions_1.getType)(ACTIONS.fetchLiveContent), handleFetchLiveContent);
    yield (0, effects_1.takeLatest)((0, typesafe_actions_1.getType)(ACTIONS.saveContent), handleSaveContent);
    yield (0, effects_1.takeLatest)((0, typesafe_actions_1.getType)(ACTIONS.publishContent), handlePublishContent);
    yield (0, effects_1.takeLatest)((0, typesafe_actions_1.getType)(ACTIONS.cloneContent), handleCloneContent);
    yield (0, effects_1.takeLatest)((0, typesafe_actions_1.getType)(ACTIONS.updatePageNode), handlePageNodeChange);
}
function* rootSaga() {
    yield (0, effects_1.all)([watch()]);
}
exports.default = rootSaga;
