package de.assecutor.votianlt.model.task;

import com.fasterxml.jackson.annotation.JsonGetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.bson.types.ObjectId;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.Field;

import java.time.LocalDateTime;

@Data
@NoArgsConstructor
@Document(collection = "tasks")
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "taskType")
@JsonSubTypes({ @JsonSubTypes.Type(value = ConfirmationTask.class, name = "CONFIRMATION"),
        @JsonSubTypes.Type(value = SignatureTask.class, name = "SIGNATURE"),
        @JsonSubTypes.Type(value = TodoListTask.class, name = "TODOLIST"),
        @JsonSubTypes.Type(value = PhotoTask.class, name = "PHOTO"),
        @JsonSubTypes.Type(value = BarcodeTask.class, name = "BARCODE"),
        @JsonSubTypes.Type(value = CommentTask.class, name = "COMMENT") })
public abstract class BaseTask {
    @Id
    @JsonIgnore
    private ObjectId id;

    @Field("station_id")
    @JsonIgnore
    private ObjectId stationId;

    @Field("job_id")
    @JsonIgnore
    private ObjectId jobId;

    @Field("station_order")
    private Integer stationOrder;

    @Field("task_order")
    private Integer taskOrder = 0;

    @Field("description")
    private String description;

    @Field("optional")
    private boolean optional = false;

    @Field("completed")
    private boolean completed = false;

    @Field("completed_at")
    private LocalDateTime completedAt;

    @Field("completed_by")
    private String completedBy;

    /**
     * Returns the ObjectId as string for JSON serialization.
     */
    @JsonGetter("id")
    public String getIdAsString() {
        return id != null ? id.toString() : null;
    }

    /**
     * Returns the station ObjectId as string for JSON serialization.
     */
    @JsonGetter("stationId")
    public String getStationIdAsString() {
        return stationId != null ? stationId.toHexString() : null;
    }

    /**
     * Returns the legacy job ObjectId as string for internal fallback handling.
     */
    public String getJobIdAsString() {
        return jobId != null ? jobId.toString() : null;
    }

    /**
     * Returns the task type as string for JSON serialization.
     */
    @JsonGetter("taskType")
    public abstract String getTaskType();

    /**
     * Returns the display name for this task type.
     */
    public abstract String getDisplayName();

    /**
     * Returns task-specific data for JSON serialization.
     */
    @JsonGetter("taskSpecificData")
    public abstract Object getTaskSpecificData();
}
