import com.liferay.portal.kernel.exception.SystemException
import cz.vrk.pi.crm.model.model.Asset
import cz.vrk.pi.crm.model.service.AssetLocalServiceUtil
import cz.vrk.pi.crm.api.asset.AssetUrlCreator
import vrk.pi.shared.ViewContext
import com.liferay.portal.kernel.log.Log
import com.liferay.portal.kernel.log.LogFactoryUtil
import java.time.Instant

def log = LogFactoryUtil.getLog("potomci")

class Dog {
    String name;
    String url;
    String sex;
    String pictureUrlThumbnail;
    String pictureUrl;
    String pictureTitle;
    Date birthdate;
    Boolean isAlive;
    List<String> extraAttr;
}

def startTime = System.currentTimeMillis()

try {
    Settings.organizationName = viewContext.organization.name;
    Family.urlCreator = urlCreator
    Family.viewContext = viewContext
    Family.originalAsset = asset
} catch (MissingPropertyException ignored) {
    //ignore zkratka tam není = null
}

if(otherAsset != null) {
    def pohlaviDefined = asset.attributes["Pohlaví"] != null && otherAsset.attributes["Pohlaví"] != null
    def pohlaviDifferent = asset.attributes["Pohlaví"] != otherAsset.attributes["Pohlaví"]

    if (pohlaviDefined && pohlaviDifferent) {
        data = [
                "descendants"            : Family.getDescendants(asset, otherAsset),
                "countOfFirstGenerations": Family.countOfFirstGenerations,
                "renderDescendants"      : Settings.renderDescendants(),
                "extraAttr"              : Settings.getExtraAttr(),
                "extraAttrName"          : Settings.getExtraAttrName(),
                "showLifeStatus"         : Settings.getShowLifeStatus(),
                "imagePath"              : Family.viewContext.themeDisplay.getPortalURL() + Family.viewContext.themeDisplay.getPathThemeRoot() + "/primefaces/outputpanel/images/loading.gif"
        ]
    } else {

        data = [
                "error": true,
                "imagePath" : Family.viewContext.themeDisplay.getPortalURL() + Family.viewContext.themeDisplay.getPathThemeRoot() + "/primefaces/outputpanel/images/loading.gif"
        ]
    }
}

log.info("\$EXTRA_HTML_ASSET_LOG HTML: 'POTOMCI POT ACCESS' ORG: '" + viewContext.organization.name + "' DATETIME: '"+ Instant.now()+"' TIME_MS: '" + (System.currentTimeMillis() - startTime) + "'")

static class Settings {
    static String organizationName;
    static String KSSP = "Klub švýcarských salašnických psů z.s.";
    static String KCHS = "Klub chovatelů špiců, z.s.";

    // nastavení pro jednotlivé organizace
    static Boolean getShowLifeStatus() {
        return false;
    }

    static Boolean getIsAlive(Asset asset) {
        return false;
    }

    static Boolean getExtraAttr() {
        if (organizationName == KSSP) {
            return true;
        }
        if (organizationName == KCHS) {
            return true;
        }
        return false;
    }

    static Boolean renderDescendants() {
        if (organizationName == KSSP) {
            return true;
        }
        if (organizationName == KCHS) {
            return true;
        }
        return false;
    }

    static List<String> getExtraAttrName() {
        List<String> names = new ArrayList();
        if (organizationName == KSSP) {
            names.add("Chovnost");
        }
        return names;
    }

    static List<String> getExtraAssetAttrName() {
        List<String> names = new ArrayList();
        if (organizationName == KSSP) {
            names.add("Chovnost");
        }
        return names;
    }
}

static class Family {
    static AssetUrlCreator urlCreator;
    static ViewContext viewContext;
    static final String MOTHER_ATTR_NAME = "Matka";
    static final String FATHER_ATTR_NAME = "Otec";
    static Asset originalAsset;
    static int countOfFirstGenerations;
    static ArrayList<String> nameAttr = Settings.getExtraAssetAttrName();


    static String calculateAge(Date birthday, Date deathday) {
        if (birthday == null || deathday == null)
            return '';

        Calendar deathDate = Calendar.getInstance();
        Calendar birthDate = Calendar.getInstance();
        birthDate.setTime(birthday);
        deathDate.setTime(deathday);

        int years = deathDate.get(Calendar.YEAR) - birthDate.get(Calendar.YEAR);
        int months = deathDate.get(Calendar.MONTH) - birthDate.get(Calendar.MONTH);

        if (months < 0) {
            years--;
            months += 12;
        }

        if (years == 0) {
            return months + " m";
        } else {
            return years + " r + " + months + " m";
        }
    }

    static Dog createDog(Asset asset) {
        long matkaId = asset.attributes[MOTHER_ATTR_NAME] == null ? 0L : asset.attributes[MOTHER_ATTR_NAME];
        long otecId = asset.attributes[FATHER_ATTR_NAME] == null ? 0L : asset.attributes[FATHER_ATTR_NAME];

        if (originalAsset.getId() == otecId || originalAsset.getId() == matkaId)  {
            countOfFirstGenerations++
        };

        def matka = AssetLocalServiceUtil.fetchAsset(matkaId)
        def otec = AssetLocalServiceUtil.fetchAsset(otecId)

        List<String> attrs = new ArrayList();
        for (String name in nameAttr) {
            if (name == "Věk dožití") {
                attrs.add(calculateAge(asset.attributes["Datum narození"], asset.attributes["Datum úhynu"]));
            } else {
                if (asset.attributes[name] instanceof Date) {
                    String attr = (Date) asset.attributes[name];
                    attrs.add(attr);
                } else {
                    String attr = asset.attributes[name];
                    attrs.add(attr);
                }
            }
        }

        return new Dog(
                name: asset.getName(),
                url: urlCreator != null ? urlCreator.getAssetDetailUrl(asset) : null,
                sex: asset.attributes["Pohlaví"] != null ? (asset.attributes["Pohlaví"].toLowerCase() == "pes" ? "pes" : "fena") : null,
                pictureUrlThumbnail: AssetLocalServiceUtil.getAssetPicture(asset) != null ? AssetLocalServiceUtil.getAssetPicture(asset).getThumbnailURL(viewContext.themeDisplay) : null,
                pictureUrl: AssetLocalServiceUtil.getAssetPicture(asset) != null ? AssetLocalServiceUtil.getAssetPicture(asset).getFullURL(viewContext.themeDisplay) : null,
                pictureTitle: AssetLocalServiceUtil.getAssetPicture(asset) != null ? AssetLocalServiceUtil.getAssetPicture(asset).getTitle() : null,
                birthdate: (Date) asset.attributes["Datum narození"],
                extraAttr: attrs,
                isAlive: Settings.getIsAlive(asset),
        )
    }

    static List<Dog> getDescendants(Asset asset, Asset otherAsset) {
        if (!Settings.renderDescendants()) {
            return new ArrayList();
        }

        List<Asset> rawDescendants = findDescendants(asset, otherAsset);
        List<Dog> descendants = new ArrayList();

        for (Asset descendant : rawDescendants) {
            descendants.add(createDog(descendant));
        }

        return descendants;
    }

    static List<Asset> findDescendants(Asset asset, Asset otherAsset) throws SystemException {
        int maxDepth = 1;

        List<Asset> descendants = new ArrayList();
        List<Long> assetIds = [asset.id]
        descendants.addAll(AssetLocalServiceUtil.getDescendants(assetIds, asset.assetDefinitionId, "Matka", "Otec", maxDepth))

        List<Asset> list = new ArrayList();
        Set<Asset> uniqueValues = new HashSet();
        for (Asset a : (descendants as List<Asset>)) {
            if (a.getId() != asset.getId()) {
                if (a.attributes[MOTHER_ATTR_NAME] == otherAsset.id || a.attributes[FATHER_ATTR_NAME] == otherAsset.id) {
                    if (uniqueValues.add(a)) {
                        list.add(a);
                    }
                }
            }
        }

        return list.sort{a -> a.attributes["Datum narození"]};
    }
}

