from sqlalchemy.orm import Session
from ..model.measurement import Measurement
from ..model.trackedchange import TrackedChange


def get_measurement_record(
    session: Session,
    is_sql_server: bool,
    device_id: int,
    historian_id: int,
    signal_type_id: int,
    point_tag: str,
    alternate_tag: str,
    signal_reference: str,
    scale: float,
    description: str,
) -> Measurement | None:
    try:
        # Lookup measurement record by signal reference, creating a new record if one does not exist
        measurement_record = (
            session.query(Measurement).filter(Measurement.SignalReference == signal_reference).one_or_none()
        )

        if measurement_record:
            # If the record exists, check if it matches the provided details
            if (
                int(measurement_record.DeviceID) == device_id
                and int(measurement_record.HistorianID) == historian_id
                and int(measurement_record.SignalTypeID) == signal_type_id
                and str(measurement_record.PointTag) == point_tag
                and str(measurement_record.AlternateTag) == alternate_tag
                and float(measurement_record.Multiplier) == scale
                and str(measurement_record.Description) == description
            ):
                return measurement_record
        else:
            measurement_record = Measurement()

        # Update record fields
        measurement_record.HistorianID = historian_id
        measurement_record.DeviceID = device_id
        measurement_record.PointTag = point_tag
        measurement_record.AlternateTag = alternate_tag
        measurement_record.SignalReference = signal_reference
        measurement_record.SignalTypeID = signal_type_id
        measurement_record.Multiplier = scale
        measurement_record.Description = description

        # Save record updates
        session.add(measurement_record)
        session.commit()

        # Re-query to get any database assigned information
        measurement_record = session.query(Measurement).filter(Measurement.SignalReference == signal_reference).one()

        if is_sql_server:
            # Manually insert the measurement record details into the TrackedChange table (in lieu of triggers)
            trackedchange_record = TrackedChange()
            trackedchange_record.TableName = "Measurement"
            trackedchange_record.PrimaryKeyColumn = "PointID"
            trackedchange_record.PrimaryKeyValue = str(measurement_record.PointID)

            session.add(trackedchange_record)
            session.commit()

            trackedchange_record = TrackedChange()
            trackedchange_record.TableName = "ActiveMeasurement"
            trackedchange_record.PrimaryKeyColumn = "SignalID"
            trackedchange_record.PrimaryKeyValue = measurement_record.SignalID

            session.add(trackedchange_record)
            session.commit()

        return measurement_record
    except Exception as e:
        session.rollback()
        print(f'Error occurred while reading or creating Measurement record for "{point_tag}: {description}": {e}')
        return None
