using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Microsoft.EntityFrameworkCore;

namespace Hc900Crawler.Core.Domain.Entities;

/// <summary>realtime_table — 실시간 모니터링 포인트</summary>
[Table("realtime_table")]
public class RealtimePoint
{
    [Column("id")]          public int     Id           { get; set; }
    [Column("tagname")]     public string  TagName      { get; set; } = string.Empty;
    [Column("node_id")]     public string  NodeId       { get; set; } = string.Empty;
    [Column("livevalue")]   public string? LiveValue    { get; set; }
    [Column("timestamp")]   public DateTime Timestamp   { get; set; } = DateTime.UtcNow;
    [Column("controller_id")] public string ControllerId { get; set; } = "HC1";
}

/// <summary>history_table — 시계열 이력 스냅샷</summary>
[Table("history_table")]
public class HistoryRecord
{
    [Column("id")]          public int     Id           { get; set; }
    [Column("tagname")]     public string  TagName      { get; set; } = string.Empty;
    [Column("node_id")]     public string  NodeId       { get; set; } = string.Empty;
    [Column("value")]       public string? Value        { get; set; }
    [Column("recorded_at")] public DateTime RecordedAt  { get; set; } = DateTime.UtcNow;
    [Column("controller_id")] public string ControllerId { get; set; } = "HC1";
}

/// <summary>P&ID 그래프 생성 작업 상태 (DB 저장용)</summary>
[Table("pid_graph_status")]
public class PidGraphStatus
{
    [Column("task_id")]    public string TaskId { get; set; } = string.Empty;
    [Column("progress")]   public double Progress { get; set; }
    [Column("status")]     public string Status { get; set; } = "Pending";
    [Column("message")]    public string Message { get; set; } = string.Empty;
    [Column("updated_at")] public DateTime UpdatedAt { get; set; } = DateTime.UtcNow;
}

/// <summary>fast_session — 데이터 수집 세션 메타</summary>
[Table("fast_session")]
public class FastSession
{
    [Column("id")]             public int       Id            { get; set; }
    [Column("name")]           public string    Name          { get; set; } = string.Empty;
    [Column("started_at")]     public DateTime  StartedAt     { get; set; }
    [Column("ended_at")]       public DateTime? EndedAt       { get; set; }
    [Column("status")]         public string    Status        { get; set; } = "Pending";
    [Column("sampling_ms")]    public int       SamplingMs    { get; set; }
    [Column("duration_sec")]   public int       DurationSec   { get; set; }
    [Column("tag_list")]       public string    TagList       { get; set; } = "[]";
    [Column("row_count")]      public int       RowCount      { get; set; }
    [Column("retention_days")] public int?      RetentionDays { get; set; }
    [Column("pinned")]         public bool      Pinned        { get; set; }
}

/// <summary>fast_record — 시계열 데이터 (Long 포맷)</summary>
[Table("fast_record")]
public class FastRecord
{
    [NotMapped]             public int      Id         { get; set; }
    [Column("session_id")]  public int      SessionId  { get; set; }
    [Column("recorded_at")] public DateTime RecordedAt { get; set; }
    [Column("tagname")]     public string   TagName    { get; set; } = string.Empty;
    [Column("value")]       public string?  Value      { get; set; }
}

/// <summary>tag_metadata — 태그 메타데이터 (변경 드묾)</summary>
[Table("tag_metadata")]
public class TagMetadata
{
    [Column("id")]          public int       Id           { get; set; }
    [Column("base_tag")]    public string    BaseTag      { get; set; } = string.Empty;
    [Column("attribute")]   public string    Attribute    { get; set; } = string.Empty;
    [Column("value")]       public string?   Value        { get; set; }
    [Column("node_id")]     public string?   NodeId       { get; set; }
    [Column("loaded_at")]   public DateTime  LoadedAt     { get; set; } = DateTime.UtcNow;
    [Column("controller_id")] public string  ControllerId { get; set; } = "HC1";
}

// ── Knowledge Base (RAG) ─────────────────────────────────────────────────────

/// <summary>kb_collections — 컬렉션 레지스트리</summary>
[Table("kb_collections")]
public class KbCollection
{
    [Key]
    [Column("collection_key")] public string CollectionKey   { get; set; } = string.Empty;
    [Column("display_name")]   public string DisplayName     { get; set; } = string.Empty;
    [Column("qdrant_name")]    public string QdrantName      { get; set; } = string.Empty;
    [Column("chunking_policy", TypeName = "jsonb")]
                               public string ChunkingPolicy  { get; set; } = "{}";
    [Column("description")]    public string? Description    { get; set; }
    [Column("is_active")]      public bool   IsActive        { get; set; } = true;
    [Column("created_at")]     public DateTime CreatedAt     { get; set; } = DateTime.UtcNow;
}

/// <summary>kb_documents — 업로드된 원본 문서 메타</summary>
[Table("kb_documents")]
public class KbDocument
{
    [Key]
    [Column("id")]              public Guid     Id             { get; set; } = Guid.NewGuid();
    [Column("collection_key")]  public string   CollectionKey  { get; set; } = string.Empty;
    [Column("title")]           public string   Title          { get; set; } = string.Empty;
    [Column("original_path")]   public string   OriginalPath   { get; set; } = string.Empty;
    [Column("file_sha256")]     public string   FileSha256     { get; set; } = string.Empty;
    [Column("file_size")]       public long?    FileSize       { get; set; }
    [Column("mime_type")]       public string?  MimeType       { get; set; }
    [Column("tags")]            public string[] Tags           { get; set; } = Array.Empty<string>();
    [Column("status")]          public string   Status         { get; set; } = "pending";
    [Column("chunk_count")]     public int      ChunkCount     { get; set; }
    [Column("error_message")]   public string?  ErrorMessage   { get; set; }
    [Column("uploaded_by")]     public string?  UploadedBy     { get; set; }
    [Column("uploaded_at")]     public DateTime UploadedAt     { get; set; } = DateTime.UtcNow;
    [Column("indexed_at")]      public DateTime? IndexedAt     { get; set; }
    [Column("disabled_at")]     public DateTime? DisabledAt    { get; set; }
}

/// <summary>kb_ingest_jobs — 비동기 처리 큐</summary>
[Table("kb_ingest_jobs")]
public class KbIngestJob
{
    [Key]
    [Column("id")]           public long      Id          { get; set; }
    [Column("doc_id")]       public Guid      DocId       { get; set; }
    [Column("stage")]        public string    Stage       { get; set; } = "parse";
    [Column("attempts")]     public int       Attempts    { get; set; }
    [Column("last_error")]   public string?   LastError   { get; set; }
    [Column("enqueued_at")]  public DateTime  EnqueuedAt  { get; set; } = DateTime.UtcNow;
    [Column("started_at")]   public DateTime? StartedAt   { get; set; }
    [Column("finished_at")]  public DateTime? FinishedAt  { get; set; }
}

/// <summary>kb_admin_credential — 관리자 비밀번호(단일 행)</summary>
[Table("kb_admin_credential")]
public class KbAdminCredential
{
    [Key]
    [Column("id")]            public int      Id            { get; set; } = 1;
    [Column("password_hash")] public string   PasswordHash  { get; set; } = string.Empty;
    [Column("salt")]          public string   Salt          { get; set; } = string.Empty;
    [Column("algorithm")]     public string   Algorithm     { get; set; } = "argon2id";
    [Column("updated_at")]    public DateTime UpdatedAt     { get; set; } = DateTime.UtcNow;
}

/// <summary>kb_admin_sessions — 관리자 세션 토큰</summary>
[Table("kb_admin_sessions")]
public class KbAdminSession
{
    [Key]
    [Column("token")]      public string   Token      { get; set; } = string.Empty;
    [Column("issued_at")]  public DateTime IssuedAt   { get; set; } = DateTime.UtcNow;
    [Column("expires_at")] public DateTime ExpiresAt  { get; set; }
    [Column("client_ip")]  public string?  ClientIp   { get; set; }
}

/// <summary>event_history_table — 디지털 포인트 상태 변경 이벤트</summary>
[Table("event_history_table")]
public class EventHistoryRecord
{
    [Key]
    [Column("id")]               public long      Id               { get; set; }
    [Column("tagname")]          public string    TagName          { get; set; } = string.Empty;
    [Column("node_id")]          public string    NodeId           { get; set; } = string.Empty;
    [Column("prev_value")]       public string?   PrevValue        { get; set; }
    [Column("curr_value")]       public string    CurrValue        { get; set; } = string.Empty;
    [Column("event_type")]       public string    EventType        { get; set; } = string.Empty;
    [Column("event_time")]       public DateTime  EventTime        { get; set; } = DateTime.UtcNow;
    [Column("area")]             public string?   Area             { get; set; }
    [Column("sub_area")]         public string?   SubArea          { get; set; }
    [Column("duration_seconds")] public int?      DurationSeconds  { get; set; }
    [Column("metadata")]         public string?   Metadata         { get; set; }
    [Column("created_at")]       public DateTime  CreatedAt        { get; set; } = DateTime.UtcNow;
    [Column("controller_id")]    public string    ControllerId     { get; set; } = "HC1";
}

/// <summary>hc900_map_master — OPC UA tagname ↔ HC900 레지스터 태그 매핑</summary>
[Table("hc900_map_master")]
public class Hc900MapEntry
{
    [Key]
    [Column("id")]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    /// <summary>태그명 (realtime_table 기준) = hc900_tag 와 동일한 Experion ItemName, e.g. "FICQ-6101.PV". 대소문자 변환 없음.</summary>
    [Column("tagname")]
    [Required]
    public string TagName { get; set; } = string.Empty;

    /// <summary>HC900 게이트웨이 register-map 태그명 (= tagname), e.g. "FICQ-6101.PV"</summary>
    [Column("hc900_tag")]
    [Required]
    public string Hc900Tag { get; set; } = string.Empty;

    [Column("modbus_addr")]
    public int ModbusAddr { get; set; }

    [Column("data_type")]
    public string DataType { get; set; } = "float32";

    [Column("access")]
    public string Access { get; set; } = "R";

    [Column("loop_no")]
    public int? LoopNo { get; set; }

    [Column("param_type")]
    public string? ParamType { get; set; }

    [Column("is_active")]
    public bool IsActive { get; set; } = true;

    [Column("controller_id")]
    public string ControllerId { get; set; } = "HC1";
}
