import com.liferay.portal.kernel.util.Base64
import cz.vrk.pi.backend.custom.EmailSettings
import cz.vrk.pi.crm.custom.EventRegistrationAssetAttribute
import cz.vrk.pi.crm.custom.MemberSectionType
import cz.vrk.pi.crm.custom.RegistrationField
import cz.vrk.pi.crm.functions.CRMFunctions
import cz.vrk.pi.crm.model.data.assets.AssetData
import cz.vrk.pi.crm.model.data.assets.AssetDataProcessor
import cz.vrk.pi.crm.model.data.assets.RegisteredAssetData
import cz.vrk.pi.crm.model.data.contact.ContactData
import cz.vrk.pi.crm.model.data.contact.ContactDataProcessor
import cz.vrk.pi.crm.model.data.event.EventDataProcessor
import cz.vrk.pi.crm.model.data.info.ParticipantsInfoGroupDataProcessor
import cz.vrk.pi.crm.model.data.member.MemberDataProcessor
import cz.vrk.pi.crm.model.model.AssetDefinition
import cz.vrk.pi.crm.model.model.ParticipantAsset
import cz.vrk.pi.crm.model.model.Participants
import cz.vrk.pi.crm.model.model.ParticipantsEventAssetFunctionViewSetting
import cz.vrk.pi.crm.model.model.ParticipantsEventViewSetting
import cz.vrk.pi.crm.model.service.AssetDefinitionLocalServiceUtil
import cz.vrk.pi.crm.model.service.ParticipantsEventSettingLocalServiceUtil
import cz.vrk.pi.crm.model.service.ParticipantsEventViewSettingLocalServiceUtil
import cz.vrk.pi.crm.model.service.ParticipantsLocalServiceUtil
import cz.vrk.pi.events.model.model.Event
import cz.vrk.pi.events.model.service.EventLocalServiceUtil
import cz.vrk.pi.ou.model.model.Contact
import cz.vrk.pi.ou.model.model.OrganizationExt
import cz.vrk.pi.ou.model.service.OrganizationExtLocalServiceUtil
import net.glxn.qrgen.QRCode
import net.glxn.qrgen.image.ImageType
import vrk.pi.shared.PIModule
import vrk.pi.shared.ViewContext

//událost s blokama
def event = EventLocalServiceUtil.fetchEventByUrlId("8faaadf0fc4006a69ab42ef3572af8ac")
def participants = ParticipantsLocalServiceUtil.getParticipantsByEvent(event.id)
//první účastník
Participants participant = participants[0]

ViewContext viewContext = new ViewContext(themeDisplay, PIModule.CRM, event.organizer.organization);
def functions = new CRMFunctions(viewContext)

def viewForms = ParticipantsEventViewSettingLocalServiceUtil.getAllViewSettings(event.id)
if (viewForms.size() == 0) {
    viewForms = [ParticipantsEventViewSettingLocalServiceUtil.getDefaultViewSetting(viewContext.organizationId, event, viewContext.locale)];
}

data = dataForRegistrationInfo(participant, event, functions, viewForms[0])


private static Map<String, Object> dataForRegistrationInfo(Participants participant, Event event, CRMFunctions crmFunctions, ParticipantsEventViewSetting viewSetting) {
    def institutionSubmitterMember = participant.getInstitutionSubmitterMember().orElse(null);
    def participatingMember = participant.getParticipatingMember();
    def participantsEventSetting = ParticipantsEventSettingLocalServiceUtil.getSettingsEnsuringExistence(event)

    HashMap<String, Object> data = new HashMap<String, Object>();
    data.put("event", EventDataProcessor.processToData(event, crmFunctions.getViewContext().getLocale()));
    OrganizationExt registeringOrganization = OrganizationExtLocalServiceUtil.getOrganizationExt(
            participatingMember.getOrganizationId());
    data.put("organization", registeringOrganization);
    data.put("sender", EmailSettings.EMAIL_FROM.getValue(registeringOrganization.id));

    data.put("participatingBlocks", participant.participatingEventBlocks)
    data.put("participantBasePrices",
            crmFunctions.getParticipantsFunctions().getParticipantBasePriceLabels(participant));
    data.put("participantServicePrices",
            crmFunctions.getParticipantsFunctions().getParticipantServicePriceLabels(participant, event));

    boolean forInstitution = participantsEventSetting.getTargetMemberSectionTypeEnum() == MemberSectionType.INSTITUTION && institutionSubmitterMember != null;
    data.put("isInstitution", forInstitution)
    if (forInstitution) {
        data.put("member", MemberDataProcessor.process(institutionSubmitterMember, crmFunctions).getData());
        data.put("institution", MemberDataProcessor.process(participatingMember, crmFunctions).getData())
        if (viewSetting != null) {
            def institutionSetting = viewSetting.getParticipantEventViewInstitutionSetting();
            List<String> showFields = new ArrayList<String>();
            for (RegistrationField field : viewSetting.personFields) {
                showFields.add(field.name());
            }
            data.put("showFields", showFields)

            List<ContactData> contacts = new ArrayList<ContactData>();
            for (Contact contact : crmFunctions.getMembers().getContacts(institutionSubmitterMember)) {
                if (!viewSetting.getPersonContactFields().keySet().contains(contact.contactType)) {
                    continue
                }
                contacts.add(ContactDataProcessor.process(contact, crmFunctions).getData());

                List<RegistrationField> contactFields = viewSetting.personContactFields.get(contact.getContactType());
                for (RegistrationField value : contactFields) {
                    showFields.add(crmFunctions.getLov().getName("CONTACT_TYPE", contact.getContactType()) + value.name());
                }
            }
            data.put("contacts", contacts);

            data.put("info", Collections.emptyList())

            List<String> showInstitutionFields = new ArrayList<String>();
            for (RegistrationField field : institutionSetting.getFields()) {
                showInstitutionFields.add(field.name());
            }
            data.put("showInstitutionFields", showInstitutionFields)

            List<ContactData> institutionContacts = new ArrayList<ContactData>();
            for (Contact contact : crmFunctions.getMembers().getContacts(participatingMember)) {
                if (!institutionSetting.contactFields.keySet().contains(contact.contactType)) {
                    continue
                }
                institutionContacts.add(ContactDataProcessor.process(contact, crmFunctions).getData());

                List<RegistrationField> contactFields = institutionSetting.contactFields.get(contact.getContactType());
                for (RegistrationField value : contactFields) {
                    showInstitutionFields.add(crmFunctions.getLov().getName("CONTACT_TYPE", contact.getContactType()) + value.name());
                }
            }
            data.put("institutionContacts", institutionContacts);

            data.put("institutionInfo", ParticipantsInfoGroupDataProcessor
                    .process(viewSetting.getEventInfoFields(), crmFunctions, participant).getData())

            data.put("institutionPersonHeading", Objects.requireNonNull(institutionSetting.getDirectedRelationship()).getReverseName())

        }
    } else {
        data.put("member", MemberDataProcessor.process(participatingMember, crmFunctions).getData());
        if (viewSetting != null) {
            List<String> showFields = new ArrayList<String>();
            for (RegistrationField field : viewSetting.personFields) {
                showFields.add(field.name());
            }
            data.put("showFields", showFields);

            List<ContactData> contacts = new ArrayList<ContactData>();
            for (Contact contact : crmFunctions.getMembers().getContacts(participatingMember)) {
                if (!viewSetting.getPersonContactFields().keySet().contains(contact.contactType)) {
                    continue
                }
                contacts.add(ContactDataProcessor.process(contact, crmFunctions).getData());

                List<RegistrationField> contactFields = viewSetting.personContactFields.get(contact.getContactType());
                for (RegistrationField value : contactFields) {
                    showFields.add(crmFunctions.getLov().getName("CONTACT_TYPE", contact.getContactType()) + value.name());
                }
            }
            data.put("contacts", contacts);

            data.put("info", ParticipantsInfoGroupDataProcessor.process(viewSetting.getEventInfoFields(),
                    crmFunctions, participant).getData());
        }
    }

    final AssetDefinition assetDefinition = AssetDefinitionLocalServiceUtil.fetchAssetDefinitionByOrganizationId(
            crmFunctions.getViewContext()
                    .getOrganizationId());

    Map<AssetDefinition, List<ParticipantsEventAssetFunctionViewSetting>> assetSettings = viewSetting.getAssetSettingsByDefinition();

    if (assetDefinition != null && assetSettings.get(assetDefinition)) {
        final List<EventRegistrationAssetAttribute> selectedAssetAttributes = assetSettings.get(assetDefinition).get(0).getAssetFields();
        data.put("assetDefinition", assetDefinition);
        List<RegisteredAssetData> list = [];
        for (ParticipantAsset a : participant.getParticipatingAssets()) {
            AssetData assetData = new AssetDataProcessor(a.getAsset(), crmFunctions).getData();
            RegisteredAssetData from = RegisteredAssetData.from(assetData, a.getAssetFunction(), selectedAssetAttributes);
            list.add(from);
        }
        data.put("registeredAssets", list);
    }

    def sendQR = true
    data.put("sendCheckInformation", sendQR)
    if (sendQR) {
        data.put("checkInCode", "12345678");
        data.put("checkInQR", Base64.encode((byte[]) generateQrCode("12345678")));
    }

    data.put("allowCancellation", false)
    return data;
}

static def generateQrCode(String checkInformationNumber) {
    ByteArrayOutputStream out = QRCode.from(checkInformationNumber)
            .to(ImageType.PNG)
            .stream();

    return out.toByteArray();
}