package at.procon.eventhub.esperpoc.persistence;

import at.procon.eventhub.esperpoc.dto.RawActivityEventDto;
import java.time.OffsetDateTime;
import java.util.List;
import java.util.UUID;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

@Repository
public class EsperPocActivityRepository {

    private final JdbcTemplate jdbcTemplate;

    public EsperPocActivityRepository(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    public List<RawActivityEventDto> findDriverActivityEvents(
            String tenantKey,
            UUID driverEntityId,
            OffsetDateTime occurredFrom,
            OffsetDateTime occurredTo
    ) {
        return jdbcTemplate.query(
                """
                select
                    event.id,
                    event.occurred_at,
                    coalesce(
                        event.payload #>> '{raw,sourceRowId}',
                        regexp_replace(event.external_source_event_id, ':(START|END)$', '')
                    ) as source_row_id,
                    event.external_source_event_id,
                    source.source_kind,
                    coalesce(pkg.extraction_code,
                        case
                            when source.source_kind = 'VEHICLE_UNIT' then 'VU_ACTIVITY'
                            else 'CARD_ACTIVITY'
                        end
                    ) as extraction_code,
                    event.driver_id,
                    event.vehicle_id,
                    event.vehicle_registration_id,
                    event.event_type,
                    event.lifecycle,
                    detail.attributes ->> 'cardSlot' as card_slot,
                    detail.attributes ->> 'cardStatus' as card_status,
                    detail.attributes ->> 'drivingStatus' as driving_status,
                    event.source_package_id
                from eventhub.event event
                join eventhub.event_source source on source.id = event.event_source_id
                join eventhub.data_package pkg on pkg.id = event.data_package_id
                left join eventhub.event_detail detail on detail.event_occurred_at = event.occurred_at
                    and detail.event_id = event.id
                    and detail.detail_type = 'DRIVER_ACTIVITY'
                where pkg.tenant_key = ?
                  and source.provider_key = 'TACHOGRAPH'
                  and (
                        (source.source_kind = 'DRIVER_CARD' and coalesce(pkg.extraction_code, 'CARD_ACTIVITY') = 'CARD_ACTIVITY')
                        or
                        (source.source_kind = 'VEHICLE_UNIT' and coalesce(pkg.extraction_code, 'VU_ACTIVITY') = 'VU_ACTIVITY')
                  )
                  and event.driver_id = ?
                  and event.occurred_at >= ?
                  and event.occurred_at < ?
                  and event.event_domain = 'DRIVER_ACTIVITY'
                  and event.event_type in ('DRIVE', 'WORK', 'AVAILABILITY', 'BREAK_REST')
                  and event.lifecycle in ('START', 'END')
                order by event.occurred_at, event.lifecycle, event.event_type, event.id
                """,
                (rs, rowNum) -> new RawActivityEventDto(
                        (UUID) rs.getObject("id"),
                        rs.getObject("occurred_at", OffsetDateTime.class),
                        rs.getString("source_row_id"),
                        rs.getString("external_source_event_id"),
                        rs.getString("source_kind"),
                        rs.getString("extraction_code"),
                        (UUID) rs.getObject("driver_id"),
                        (UUID) rs.getObject("vehicle_id"),
                        (UUID) rs.getObject("vehicle_registration_id"),
                        rs.getString("event_type"),
                        rs.getString("lifecycle"),
                        rs.getString("card_slot"),
                        rs.getString("card_status"),
                        rs.getString("driving_status"),
                        rs.getString("source_package_id")
                ),
                tenantKey,
                driverEntityId,
                occurredFrom,
                occurredTo
        );
    }
}
