"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 __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __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());
    });
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const React = __importStar(require("react"));
const PropTypes = __importStar(require("prop-types"));
const VirtualSchemaField_1 = __importDefault(require("../VirtualSchemaField"));
const utils_1 = require("../../utils");
const unitFilterPropType = PropTypes.shape({
    field: PropTypes.string.isRequired,
    valueIn: PropTypes.arrayOf(PropTypes.string).isRequired
});
/**
 * Watches a specified field which contains a year.
 *
 * Fetches taxa observed in the specified year and adds them to the units in formData.
 *
 * uiSchema = {
 *   "ui:field": "TaxaByYearPopulatorField",
 *   "ui:options": {
 *     "collectionID": "HR.6920",                       // Collection ID to fetch documents from
 *     "unitFilter": {                                  // Filter for units from fetched documents
 *       "field": "observationStatus",                  // Field to filter on
 *       "valueIn": ["MY.observationStatusObservedNoCount", ...] // Allowed values
 *     }
 *   }
 * }
 */
let TaxaByYearPopulatorField = class TaxaByYearPopulatorField extends React.Component {
    constructor() {
        super(...arguments);
        this.onChange = (formData) => __awaiter(this, void 0, void 0, function* () {
            yield this.populateTaxa(formData);
        });
    }
    static getName() {
        return "TaxaByYearPopulatorField";
    }
    getStateFromProps() {
        return { onChange: this.onChange };
    }
    componentDidMount() {
        return __awaiter(this, void 0, void 0, function* () {
            yield this.populateTaxa(this.props.formData);
        });
    }
    populateTaxa(formData) {
        return __awaiter(this, void 0, void 0, function* () {
            var _a, _b, _c, _d, _e, _f, _g;
            if (!((_a = formData === null || formData === void 0 ? void 0 : formData.gatheringEvent) === null || _a === void 0 ? void 0 : _a.dateBegin)) {
                this.props.onChange(formData);
                return;
            }
            const { collectionID, unitFilter } = (0, utils_1.getUiOptions)(this.props.uiSchema);
            const namedPlace = formData === null || formData === void 0 ? void 0 : formData.namedPlaceID;
            const observationYear = Number((_c = (_b = formData === null || formData === void 0 ? void 0 : formData.gatheringEvent) === null || _b === void 0 ? void 0 : _b.dateBegin) === null || _c === void 0 ? void 0 : _c.split("-")[0]) || undefined;
            const res = yield this.fetchTaxaFromNamedPlace(this.props, collectionID, namedPlace, observationYear);
            let fetchedUnits = res.flatMap(doc => doc.gatherings.flatMap(g => g.units));
            if ((unitFilter === null || unitFilter === void 0 ? void 0 : unitFilter.field) && (unitFilter === null || unitFilter === void 0 ? void 0 : unitFilter.valueIn)) {
                fetchedUnits = fetchedUnits.filter((u) => u[unitFilter.field] && unitFilter.valueIn.includes(u[unitFilter.field]));
            }
            if (fetchedUnits.length === 0) {
                this.props.onChange(formData);
                return;
            }
            const seen = new Set();
            const identifications = fetchedUnits.flatMap(u => u.identifications).filter(id => {
                if (!id.taxonID || seen.has(id.taxonID))
                    return false;
                seen.add(id.taxonID);
                return true;
            });
            const tmpIdTree = this.props.formContext.services.ids.getRelativeTmpIdTree(this.props.idSchema.$id + "_units");
            const formUnits = ((_e = (_d = formData.gatherings) === null || _d === void 0 ? void 0 : _d[0]) === null || _e === void 0 ? void 0 : _e.units)
                ? [...formData.gatherings[0].units].filter((unit) => { var _a; return (_a = unit.unitFact) === null || _a === void 0 ? void 0 : _a.autocompleteSelectedTaxonID; })
                : [];
            identifications.forEach((identification) => {
                if (!formUnits.some((u) => { var _a; return ((_a = u.unitFact) === null || _a === void 0 ? void 0 : _a.autocompleteSelectedTaxonID) === identification.taxonID; })) {
                    formUnits.push((0, utils_1.addLajiFormIds)({
                        identifications: [{
                                taxon: identification.taxonVerbatim
                            }],
                        unitFact: {
                            autocompleteSelectedTaxonID: identification.taxonID
                        }
                    }, tmpIdTree, false)[0]);
                }
            });
            this.props.onChange(Object.assign(Object.assign({}, formData), { gatherings: [
                    Object.assign(Object.assign({}, (((_f = formData.gatherings) === null || _f === void 0 ? void 0 : _f[0]) || {})), { units: formUnits }),
                    ...(((_g = formData.gatherings) === null || _g === void 0 ? void 0 : _g.slice(1)) || [])
                ] }));
            return;
        });
    }
    fetchTaxaFromNamedPlace(props, collectionID, namedPlace, observationYear) {
        return __awaiter(this, void 0, void 0, function* () {
            var _a;
            const apiClient = (_a = props.formContext) === null || _a === void 0 ? void 0 : _a.apiClient;
            if (!apiClient) {
                return [];
            }
            try {
                const response = yield apiClient.get("/documents", {
                    query: {
                        collectionID,
                        namedPlace,
                        observationYear,
                        selfAsEditorOrCreator: true,
                        pageSize: 1000,
                        page: 1
                    }
                });
                if (!response.results || !Array.isArray(response.results)) {
                    return [];
                }
                return response.results;
            }
            catch (error) {
                return [];
            }
        });
    }
};
TaxaByYearPopulatorField.propTypes = {
    uiSchema: PropTypes.shape({
        "ui:options": PropTypes.shape({
            collectionID: PropTypes.string,
            unitFilter: unitFilterPropType
        }),
        uiSchema: PropTypes.object
    }).isRequired,
    schema: PropTypes.shape({
        type: PropTypes.oneOf(["array", "object"])
    }).isRequired,
    formData: PropTypes.oneOfType([PropTypes.array, PropTypes.object]).isRequired
};
TaxaByYearPopulatorField = __decorate([
    VirtualSchemaField_1.default
], TaxaByYearPopulatorField);
exports.default = TaxaByYearPopulatorField;
