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

namespace bitforum.Models.BBS
{
    [Table("BoardMeta")]
    public class BoardMeta
    {
        [ForeignKey("BoardID")]
        public Board Board { get; set; } = null!;

        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        [DisplayName("PK")]
        [Comment("PK")]
        public int ID { get; set; }

        [Required]
        [DisplayName("게시판 ID")]
        [Comment("게시판 ID")]
        public int BoardID { get; set; }

        // 목록
        public BoardListMeta List { get; set; } = new BoardListMeta();

        // 권한
        public BoardPermissionMeta Permission { get; set; } = new BoardPermissionMeta();

        // 알람
        public BoardNotifyMeta Notify { get; set; } = new BoardNotifyMeta();

        // 경험치
        public BoardExpMeta Exp { get; set; } = new BoardExpMeta();
    }

    /// <summary>
    /// 게시판 목록 설정
    /// </summary>
    [Owned]
    public class BoardListMeta
    {
        [DisplayName("상단 내용")]
        [Comment("상단 내용")]
        public string? HeaderContent { get; set; } = null;

        [DisplayName("하단 내용")]
        [Comment("하단 내용")]
        public string? FooterContent { get; set; } = null;

        [DisplayName("게시판 종류")]
        [Comment("게시판 종류")]
        public BoardConst.Layout? Layout { get; set; }

        [DisplayName("기본 정렬")]
        [Comment("기본 정렬")]
        public BoardConst.OrderBy? OrderBy { get; set; }

        [DisplayName("목록 표시")]
        [Comment("목록 표시")]
        public byte PerPage { get; set; } = 0;

        [DisplayName("글쓰기 버튼 보이기")]
        [Comment("글쓰기 버튼 보이기")]
        public bool AlwaysShowWriteButton { get; set; } = false;

        [DisplayName("하단 목록 보이기")]
        [Comment("하단 목록 보이기")]
        public bool ShowFooterListView { get; set; } = false;

        [DisplayName("NEW 사용 여부")]
        [Comment("NEW 사용 여부")]
        public bool IsNewIcon { get; set; } = false;

        [DisplayName("HOT 사용 여부")]
        [Comment("HOT 사용 여부")]
        public bool IsHotIcon { get; set; } = false;

        [DisplayName("공지사항 제외 여부")]
        [Comment("공지사항 제외 여부")]
        public bool ExceptNotice { get; set; } = false;

        [DisplayName("전체공지 제외 여부")]
        [Comment("전체공지 제외 여부")]
        public bool ExceptSpeaker { get; set; } = false;
    }

    /// <summary>
    /// 게시판 권한 설정
    /// </summary>
    [Owned]
    public class BoardPermissionMeta
    {
        [DisplayName("게시판 접근")]
        [Comment("게시판 접근")]
        public BoardConst.Permission BoardAccess { get; set; }

        [DisplayName("글 열람")]
        [Comment("글 열람")]
        public BoardConst.Permission PostView { get; set; }

        [DisplayName("글 작성")]
        [Comment("글 작성")]
        public BoardConst.Permission PostWrite { get; set; }

        [DisplayName("댓글 목록")]
        [Comment("댓글 목록")]
        public BoardConst.Permission CommentView { get; set; }

        [DisplayName("댓글 작성")]
        [Comment("댓글 작성")]
        public BoardConst.Permission CommentWrite { get; set; }

        [DisplayName("답글 작성")]
        [Comment("답글 작성")]
        public BoardConst.Permission ReplyWrite { get; set; }

        [DisplayName("파일 업로드")]
        [Comment("파일 업로드")]
        public BoardConst.Permission FileUpload { get; set; }

        [DisplayName("파일 다운로드")]
        [Comment("파일 다운로드")]
        public BoardConst.Permission FileDownload { get; set; }
    }

    [Owned]
    public class BoardNotifyMeta
    {
        [DisplayName("게시글 작성 시")]
        [Comment("게시글 작성 시")]
        public BoardConst.Notify? PostWriteNotify { get; set; } = null;

        [DisplayName("댓글 작성 시")]
        [Comment("댓글 작성 시")]
        public BoardConst.Notify? CommentWriteNotify { get; set; } = null;

        [DisplayName("답글 작성 시")]
        [Comment("답글 작성 시")]
        public BoardConst.Notify? ReplyWriteNotify { get; set; } = null;
    }

    /// <summary>
    /// 게시판 경험치 설정
    /// </summary>
    [Owned]
    public class BoardExpMeta
    {
        [DisplayName("경험치 기능")]
        [Comment("경험치 기능")]
        public bool EnableExp { get; set; } = false;

        [DisplayName("경험치 안내")]
        [Comment("경험치 안내")]
        public bool ShowExpGuide { get; set; } = false;

        /*
         * 경험치 지급량 조절
         */
        [DisplayName("게시글 작성")]
        [Comment("게시글 작성")]
        [Range(0, 10000, ErrorMessage = "값은 0 ~ 10,000 사이를 입력합니다.")]
        public ushort PostWriteExp { get; set; } = 0;

        [DisplayName("댓글 작성")]
        [Comment("댓글 작성")]
        [Range(0, 10000, ErrorMessage = "값은 0 ~ 10,000 사이를 입력합니다.")]
        public ushort CommentWriteExp { get; set; } = 0;

        [DisplayName("파일 업로드")]
        [Comment("파일 업로드")]
        [Range(0, 10000, ErrorMessage = "값은 0 ~ 10,000 사이를 입력합니다.")]
        public ushort FileUploadExp { get; set; } = 0;

        [DisplayName("파일 다운로드")]
        [Comment("파일 다운로드")]
        [Range(-10000, 10000, ErrorMessage = "값은 -10,000 ~ 10,000 사이를 입력합니다.")]
        public short FileDownloadExp { get; set; } = 0;

        [DisplayName("게시글 읽기")]
        [Comment("게시글 읽기")]
        [Range(-10000, 10000, ErrorMessage = "값은 -10,000 ~ 10,000 사이를 입력합니다.")]
        public short OtherPostReadExp { get; set; } = 0;

        [DisplayName("게시글 좋아요")]
        [Comment("게시글 좋아요")]
        [Range(0, 10000, ErrorMessage = "값은 0 ~ 10,000 사이를 입력합니다.")]
        public ushort OtherPostLikeExp { get; set; } = 0;

        [DisplayName("게시글 싫어요")]
        [Comment("게시글 싫어요")]
        [Range(0, 10000, ErrorMessage = "값은 0 ~ 10,000 사이를 입력합니다.")]
        public ushort OtherPostDisLikeExp { get; set; } = 0;

        [DisplayName("댓글 좋아요")]
        [Comment("댓글 좋아요")]
        [Range(0, 10000, ErrorMessage = "값은 0 ~ 10,000 사이를 입력합니다.")]
        public ushort OtherCommentLikeExp { get; set; } = 0;

        [DisplayName("댓글 싫어요")]
        [Comment("댓글 싫어요")]
        [Range(0, 10000, ErrorMessage = "값은 0 ~ 10,000 사이를 입력합니다.")]
        public ushort OtherCommentDisLikeExp { get; set; } = 0;

        [DisplayName("내 게시글 읽힘")]
        [Comment("내 게시글 읽힘")]
        [Range(0, 10000, ErrorMessage = "값은 0 ~ 10,000 사이를 입력합니다.")]
        public ushort OwnPostReadExp { get; set; } = 0;

        [DisplayName("내 게시글 좋아요")]
        [Comment("내 게시글 좋아요")]
        [Range(0, 10000, ErrorMessage = "값은 0 ~ 10,000 사이를 입력합니다.")]
        public ushort OwnPostLikeExp { get; set; } = 0;

        [DisplayName("내 게시글 싫어요")]
        [Comment("내 게시글 싫어요")]
        [Range(-10000, 10000, ErrorMessage = "값은 -10,000 ~ 10,000 사이를 입력합니다.")]
        public short OwnPostDisLikeExp { get; set; } = 0;

        [DisplayName("내 댓글 좋아요")]
        [Comment("내 댓글 좋아요")]
        [Range(0, 10000, ErrorMessage = "값은 0 ~ 10,000 사이를 입력합니다.")]
        public ushort OwnCommentLikeExp { get; set; } = 0;

        [DisplayName("내 댓글 싫어요")]
        [Comment("내 댓글 싫어요")]
        [Range(-10000, 10000, ErrorMessage = "값은 -10,000 ~ 10,000 사이를 입력합니다.")]
        public short OwnCommentDisLikeExp { get; set; } = 0;

        /*
         * 경험치 회수량 조절 (항상 음수 계산)
         */
        [DisplayName("게시글 작성 취소")]
        [Comment("게시글 작성 취소")]
        [Range(0, 10000, ErrorMessage = "값은 0 ~ 10,000 사이를 입력합니다.")]
        public ushort PostWriteUndoExp { get; set; } = 0;

        [DisplayName("댓글 작성 취소")]
        [Comment("댓글 작성 취소")]
        [Range(0, 10000, ErrorMessage = "값은 0 ~ 10,000 사이를 입력합니다.")]
        public ushort CommentWriteUndoExp { get; set; } = 0;

        [DisplayName("파일 업로드 취소")]
        [Comment("파일 업로드 취소")]
        [Range(0, 10000, ErrorMessage = "값은 0 ~ 10,000 사이를 입력합니다.")]
        public ushort FileUploadUndoExp { get; set; } = 0;

        [DisplayName("게시글 읽기 취소")]
        [Comment("게시글 읽기 취소")]
        [Range(0, 10000, ErrorMessage = "값은 0 ~ 10,000 사이를 입력합니다.")]
        public ushort OtherPostReadUndoExp { get; set; } = 0;

        [DisplayName("게시글 좋아요 취소")]
        [Comment("게시글 좋아요 취소")]
        [Range(0, 10000, ErrorMessage = "값은 0 ~ 10,000 사이를 입력합니다.")]
        public ushort OtherPostLikeUndoExp { get; set; } = 0;

        [DisplayName("게시글 싫어요 취소")]
        [Comment("게시글 싫어요 취소")]
        [Range(0, 10000, ErrorMessage = "값은 0 ~ 10,000 사이를 입력합니다.")]
        public ushort OtherPostDisLikeUndoExp { get; set; } = 0;

        [DisplayName("댓글 좋아요 취소")]
        [Comment("댓글 좋아요 취소")]
        [Range(0, 10000, ErrorMessage = "값은 0 ~ 10,000 사이를 입력합니다.")]
        public ushort OtherCommentLikeUndoExp { get; set; } = 0;

        [DisplayName("댓글 싫어요 취소")]
        [Comment("댓글 싫어요 취소")]
        [Range(0, 10000, ErrorMessage = "값은 0 ~ 10,000 사이를 입력합니다.")]
        public ushort OtherCommentDisLikeUndoExp { get; set; } = 0;

        [DisplayName("내 게시글 읽힘 취소")]
        [Comment("내 게시글 읽힘 취소")]
        [Range(0, 10000, ErrorMessage = "값은 0 ~ 10,000 사이를 입력합니다.")]
        public ushort OwnPostReadUndoExp { get; set; } = 0;

        [DisplayName("내 게시글 좋아요 취소")]
        [Comment("내 게시글 좋아요 취소")]
        [Range(0, 10000, ErrorMessage = "값은 0 ~ 10,000 사이를 입력합니다.")]
        public ushort OwnPostLikeUndoExp { get; set; } = 0;

        [DisplayName("내 게시글 싫어요 취소")]
        [Comment("내 게시글 싫어요 취소")]
        [Range(0, 10000, ErrorMessage = "값은 0 ~ 10,000 사이를 입력합니다.")]
        public ushort OwnPostDisLikeUndoExp { get; set; } = 0;

        [DisplayName("내 댓글 좋아요 취소")]
        [Comment("내 댓글 좋아요 취소")]
        [Range(0, 10000, ErrorMessage = "값은 0 ~ 10,000 사이를 입력합니다.")]
        public ushort OwnCommentLikeUndoExp { get; set; } = 0;

        [DisplayName("내 댓글 싫어요 취소")]
        [Comment("내 댓글 싫어요 취소")]
        [Range(0, 10000, ErrorMessage = "값은 0 ~ 10,000 사이를 입력합니다.")]
        public ushort OwnCommentDisLikeUndoExp { get; set; } = 0;

        /*
         * 경험치 지급 기한
         */
        [DisplayName("게시글 작성 기한")]
        [Comment("게시글 작성 기한")]
        [Range(0, 365, ErrorMessage = "값은 0 ~ 365 사이를 입력합니다.")]
        public ushort PostWriteExpWithinDays { get; set; } = 0;

        [DisplayName("댓글 작성 기한")]
        [Comment("댓글 작성 기한")]
        [Range(0, 365, ErrorMessage = "값은 0 ~ 365 사이를 입력합니다.")]
        public ushort CommentWriteExpWithinDays { get; set; } = 0;

        [DisplayName("파일 업로드 기한")]
        [Comment("파일 업로드 기한")]
        [Range(0, 365, ErrorMessage = "값은 0 ~ 365 사이를 입력합니다.")]
        public ushort FileUploadExpWithinDays { get; set; } = 0;

        [DisplayName("게시글 읽기 기한")]
        [Comment("게시글 읽기 기한")]
        [Range(0, 365, ErrorMessage = "값은 0 ~ 365 사이를 입력합니다.")]
        public ushort OtherPostReadExpWithinDays { get; set; } = 0;

        [DisplayName("게시글 좋아요 기한")]
        [Comment("게시글 좋아요 기한")]
        [Range(0, 365, ErrorMessage = "값은 0 ~ 365 사이를 입력합니다.")]
        public ushort OtherPostLikeExpWithinDays { get; set; } = 0;

        [DisplayName("게시글 싫어요 기한")]
        [Comment("게시글 싫어요 기한")]
        [Range(0, 365, ErrorMessage = "값은 0 ~ 365 사이를 입력합니다.")]
        public ushort OtherPostDisLikeExpWithinDays { get; set; } = 0;

        [DisplayName("댓글 좋아요 기한")]
        [Comment("댓글 좋아요 기한")]
        [Range(0, 365, ErrorMessage = "값은 0 ~ 365 사이를 입력합니다.")]
        public ushort OtherCommentLikeExpWithinDays { get; set; } = 0;

        [DisplayName("댓글 싫어요 기한")]
        [Comment("댓글 싫어요 기한")]
        [Range(0, 365, ErrorMessage = "값은 0 ~ 365 사이를 입력합니다.")]
        public ushort OtherCommentDisLikeExpWithinDays { get; set; } = 0;

        [DisplayName("내 게시글 읽힘 기한")]
        [Comment("내 게시글 읽힘 기한")]
        [Range(0, 365, ErrorMessage = "값은 0 ~ 365 사이를 입력합니다.")]
        public ushort OwnPostReadExpWithinDays { get; set; } = 0;

        [DisplayName("내 게시글 좋아요 기한")]
        [Comment("내 게시글 좋아요 기한")]
        [Range(0, 365, ErrorMessage = "값은 0 ~ 365 사이를 입력합니다.")]
        public ushort OwnPostLikeExpWithinDays { get; set; } = 0;

        [DisplayName("내 게시글 싫어요 기한")]
        [Comment("내 게시글 싫어요 기한")]
        [Range(0, 365, ErrorMessage = "값은 0 ~ 365 사이를 입력합니다.")]
        public ushort OwnPostDisLikeExpWithinDays { get; set; } = 0;

        [DisplayName("내 댓글 좋아요 기한")]
        [Comment("내 댓글 좋아요 기한")]
        [Range(0, 365, ErrorMessage = "값은 0 ~ 365 사이를 입력합니다.")]
        public ushort OwnCommentLikeExpWithinDays { get; set; } = 0;

        [DisplayName("내 댓글 싫어요 기한")]
        [Comment("내 댓글 싫어요 기한")]
        [Range(0, 365, ErrorMessage = "값은 0 ~ 365 사이를 입력합니다.")]
        public ushort OwnCommentDisLikeExpWithinDays { get; set; } = 0;
    }

    /// <summary>
    /// 게시판 알림 양식
    /// </summary>
    [Owned]
    public class BoardNotifyTemplateMeta
    {
        [DisplayName("이메일 제목 - 게시글 작성 시")]
        [Comment("이메일 제목 - 게시글 작성 시")]
        public string? PostWriteEmailNotifySubject { get; set; } = null;

        [DisplayName("이메일 내용 - 게시글 작성 시")]
        [Comment("이메일 내용 - 게시글 작성 시")]
        public string? PostWriteEmailNotifyContent { get; set; } = null;

        [DisplayName("이메일 제목 - 댓글 작성 시")]
        [Comment("이메일 제목 - 댓글 작성 시")]
        public string? CommentWriteEmailNotifySubject { get; set; } = null;

        [DisplayName("이메일 내용 - 댓글 작성 시")]
        [Comment("이메일 내용 - 댓글 작성 시")]
        public string? CommentWriteEmailNotifyContent { get; set; } = null;

        [DisplayName("이메일 제목 - 답글 작성 시")]
        [Comment("이메일 제목 - 답글 작성 시")]
        public string? ReplyWriteEmailNotifySubject { get; set; } = null;

        [DisplayName("이메일 내용 - 답글 작성 시")]
        [Comment("이메일 내용 - 답글 작성 시")]
        public string? ReplyWriteEmailNotifyContent { get; set; } = null;
    }
}