package com.dne.ems.model;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;

import com.dne.ems.model.enums.PollutionType;
import com.dne.ems.model.enums.SeverityLevel;
import com.dne.ems.model.enums.TaskStatus;

import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany;
import jakarta.persistence.OneToOne;
import jakarta.persistence.Table;
import lombok.Data;

/**
 * 网格任务实体
 *
 * <p>表示由网格工作人员执行的任务，通常根据用户反馈创建，
 * 包含解决报告问题所需的所有详细信息，映射到'tasks'表。
 *
 * <p>主要功能：
 * <ul>
 *   <li>记录任务详情和要求</li>
 *   <li>跟踪任务状态和进度</li>
 *   <li>关联工作人员和反馈</li>
 * </ul>
 *
 * @author DNE开发团队
 * @version 1.2
 * @since 2025-06-16
 */
@Data
@Entity
@Table(name = "tasks")
public class Task {

    /**
     * 主键ID，任务的唯一标识
     */
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    /**
     * 关联的原始反馈
     *
     * <p>可为null，表示手动创建的任务
     */
    @OneToOne
    @JoinColumn(name = "feedback_id")
    private Feedback feedback;

    /**
     * The grid worker to whom this task is assigned.
     */
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "assignee_id")
    private UserAccount assignee;

    /**
     * The user (typically a supervisor) who created this task.
     */
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "created_by")
    private UserAccount createdBy;

    /**
     * The current status of the task (e.g., PENDING, IN_PROGRESS, COMPLETED).
     */
    @Enumerated(EnumType.STRING)
    @Column(nullable = false)
    private TaskStatus status;

    /**
     * The timestamp when the task was assigned to the worker.
     */
    @Column(name = "assigned_at")
    private LocalDateTime assignedAt;

    /**
     * The timestamp when the task was marked as completed.
     */
    @Column(name = "completed_at")
    private LocalDateTime completedAt;

    /**
     * The timestamp when the task was created. Automatically managed by Hibernate.
     */
    @CreationTimestamp
    @Column(name = "created_at", nullable = false, updatable = false)
    private LocalDateTime createdAt;

    /**
     * The timestamp when the task was last updated. Automatically managed by Hibernate.
     */
    @UpdateTimestamp
    @Column(name = "updated_at", nullable = false)
    private LocalDateTime updatedAt;

    /**
     * A brief title for the task.
     */
    private String title;

    /**
     * A detailed description of the task requirements.
     */
    @Column(columnDefinition = "TEXT")
    private String description;

    /**
     * The type of pollution this task addresses.
     */
    @Enumerated(EnumType.STRING)
    private PollutionType pollutionType;

    /**
     * The severity level of the issue.
     */
    @Enumerated(EnumType.STRING)
    private SeverityLevel severityLevel;

    /**
     * A human-readable text address for the task location.
     */
    private String textAddress;

    /**
     * The x-coordinate of the grid cell where the task is located.
     */
    private Integer gridX;

    /**
     * The y-coordinate of the grid cell where the task is located.
     */
    private Integer gridY;

    /**
     * The geographical latitude of the task location.
     */
    private Double latitude;

    /**
     * The geographical longitude of the task location.
     */
    private Double longitude;

    /**
     * A list of history records for this task, tracking all status changes and updates.
     * Managed with a one-to-many relationship, and orphan removal ensures that
     * history records are deleted when the task is deleted.
     */
    @OneToMany(mappedBy = "task", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<TaskHistory> history = new ArrayList<>();

    /**
     * The assignment details for this task.
     * This establishes a bidirectional link between a task and its assignment.
     */
    @OneToOne(mappedBy = "task", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private Assignment assignment;

    /**
     * A list of all submissions made for this task.
     * Managed with a one-to-many relationship.
     */
    @OneToMany(mappedBy = "task", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<TaskSubmission> submissions = new ArrayList<>();
}