/*
 * 自然写教学资源管理与内容分发系统软件 V1.0
 * model/Resource.java - 资源数据模型
 * model/DotPattern.java - 点阵码模型
 * model/AuditRecord.java - 审核记录模型
 * config/OssConfig.java - OSS对象存储配置
 * config/ElasticsearchConfig.java - ES配置
 * security/ResourceSecurity.java - 资源安全（防盗链+水印）
 */
package com.writech.resource.model;

import java.util.*;

/**
 * 资源数据模型（对应MySQL resource表）
 */
public class Resource {

    /** 资源ID（UUID） */
    private String id;

    /** 资源名称 */
    private String name;

    /** 资源描述 */
    private String description;

    /** 资源类型（COURSEWARE/COPYBOOK/EXAM_PAPER/TEMPLATE/DOT_CODE/VIDEO） */
    private String type;

    /** 学科 */
    private String subject;

    /** 适用年级 */
    private String grade;

    /** 出版社 */
    private String publisher;

    /** 版本号 */
    private String version;

    /** 审核状态（PENDING/APPROVED/REJECTED/WITHDRAWN） */
    private String auditStatus;

    /** OSS文件存储Key */
    private String fileKey;

    /** 文件大小（字节） */
    private long fileSize;

    /** MIME类型 */
    private String mimeType;

    /** 缩略图URL */
    private String thumbnailUrl;

    /** 上传者ID */
    private String uploaderId;

    /** 上传者姓名 */
    private String uploaderName;

    /** 所属学校ID */
    private String schoolId;

    /** 标签（逗号分隔） */
    private String tags;

    /** 下载次数 */
    private int downloadCount;

    /** 使用次数 */
    private int useCount;

    /** 创建时间 */
    private Date createdAt;

    /** 更新时间 */
    private Date updatedAt;

    /** 是否已删除（软删除标记） */
    private boolean deleted;

    // ============================================================
    //  Getter / Setter
    // ============================================================

    public String getId() { return id; }
    public void setId(String id) { this.id = id; }
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public String getDescription() { return description; }
    public void setDescription(String description) { this.description = description; }
    public String getType() { return type; }
    public void setType(String type) { this.type = type; }
    public String getSubject() { return subject; }
    public void setSubject(String subject) { this.subject = subject; }
    public String getGrade() { return grade; }
    public void setGrade(String grade) { this.grade = grade; }
    public String getPublisher() { return publisher; }
    public void setPublisher(String publisher) { this.publisher = publisher; }
    public String getVersion() { return version; }
    public void setVersion(String version) { this.version = version; }
    public String getAuditStatus() { return auditStatus; }
    public void setAuditStatus(String auditStatus) { this.auditStatus = auditStatus; }
    public String getFileKey() { return fileKey; }
    public void setFileKey(String fileKey) { this.fileKey = fileKey; }
    public long getFileSize() { return fileSize; }
    public void setFileSize(long fileSize) { this.fileSize = fileSize; }
    public String getMimeType() { return mimeType; }
    public void setMimeType(String mimeType) { this.mimeType = mimeType; }
    public String getThumbnailUrl() { return thumbnailUrl; }
    public void setThumbnailUrl(String thumbnailUrl) { this.thumbnailUrl = thumbnailUrl; }
    public String getUploaderId() { return uploaderId; }
    public void setUploaderId(String uploaderId) { this.uploaderId = uploaderId; }
    public String getSchoolId() { return schoolId; }
    public void setSchoolId(String schoolId) { this.schoolId = schoolId; }
    public String getTags() { return tags; }
    public void setTags(String tags) { this.tags = tags; }
    public int getDownloadCount() { return downloadCount; }
    public int getUseCount() { return useCount; }
    public Date getCreatedAt() { return createdAt; }
    public Date getUpdatedAt() { return updatedAt; }
    public boolean isDeleted() { return deleted; }
    public void setDeleted(boolean deleted) { this.deleted = deleted; }

    @Override
    public String toString() {
        return "Resource{id='" + id + "', name='" + name + "', type='" + type +
               "', subject='" + subject + "', grade='" + grade + "'}";
    }
}

/**
 * 点阵码模型（对应MySQL dot_pattern表 + OSS文件）
 */
class DotPattern {

    /** 点阵码ID（全局唯一） */
    private long dotCodeId;

    /** 关联的资源ID */
    private String resourceId;

    /** 页面序号 */
    private int pageIndex;

    /** 区域类型 */
    private String areaType;

    /** 区域坐标和尺寸（mm） */
    private double areaX;
    private double areaY;
    private double areaWidth;
    private double areaHeight;

    /** 点阵码图案文件OSS Key */
    private String patternFileKey;

    /** 生成参数JSON */
    private String generateParams;

    /** 状态（ACTIVE/REVOKED） */
    private String status;

    /** 创建时间 */
    private Date createdAt;

    public long getDotCodeId() { return dotCodeId; }
    public void setDotCodeId(long id) { this.dotCodeId = id; }
    public String getResourceId() { return resourceId; }
    public void setResourceId(String rid) { this.resourceId = rid; }
    public int getPageIndex() { return pageIndex; }
    public void setPageIndex(int idx) { this.pageIndex = idx; }
    public String getAreaType() { return areaType; }
    public void setAreaType(String type) { this.areaType = type; }
    public double getAreaX() { return areaX; }
    public double getAreaY() { return areaY; }
    public double getAreaWidth() { return areaWidth; }
    public double getAreaHeight() { return areaHeight; }
    public String getPatternFileKey() { return patternFileKey; }
    public String getStatus() { return status; }
    public void setStatus(String status) { this.status = status; }
    public Date getCreatedAt() { return createdAt; }
}

/**
 * 审核记录模型（对应MySQL audit_record表）
 */
class AuditRecord {

    /** 记录ID */
    private String id;

    /** 关联的资源ID */
    private String resourceId;

    /** 审核人ID */
    private String auditorId;

    /** 审核人姓名 */
    private String auditorName;

    /** 审核操作（APPROVE/REJECT/RETURN/WITHDRAW） */
    private String action;

    /** 审核意见 */
    private String comment;

    /** 审核前状态 */
    private String preStatus;

    /** 审核后状态 */
    private String postStatus;

    /** 审核时间 */
    private Date createdAt;

    public String getId() { return id; }
    public void setId(String id) { this.id = id; }
    public String getResourceId() { return resourceId; }
    public void setResourceId(String rid) { this.resourceId = rid; }
    public String getAuditorId() { return auditorId; }
    public void setAuditorId(String aid) { this.auditorId = aid; }
    public String getAction() { return action; }
    public void setAction(String action) { this.action = action; }
    public String getComment() { return comment; }
    public void setComment(String comment) { this.comment = comment; }
    public String getPreStatus() { return preStatus; }
    public String getPostStatus() { return postStatus; }
    public Date getCreatedAt() { return createdAt; }
}

/**
 * OSS对象存储配置
 *
 * 多副本冗余存储（99.99%数据持久性），
 * 支持STS临时凭证直传，生命周期管理。
 */
class OssConfig {

    /** OSS区域端点 */
    private String endpoint;

    /** 存储桶名称 */
    private String bucketName;

    /** AccessKey ID */
    private String accessKeyId;

    /** AccessKey Secret（加密存储） */
    private String accessKeySecret;

    /** STS角色ARN（用于前端直传临时授权） */
    private String stsRoleArn;

    /** STS会话名称 */
    private String stsSessionName;

    /** 资源前缀路径 */
    private String resourcePrefix;

    /** 缩略图前缀路径 */
    private String thumbnailPrefix;

    /** 临时文件过期天数 */
    private int tempFileExpireDays;

    public OssConfig() {
        this.endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
        this.bucketName = "writech-resources";
        this.resourcePrefix = "resources/";
        this.thumbnailPrefix = "thumbnails/";
        this.tempFileExpireDays = 7;
        this.stsSessionName = "writech-upload-session";
    }

    public String getEndpoint() { return endpoint; }
    public void setEndpoint(String ep) { this.endpoint = ep; }
    public String getBucketName() { return bucketName; }
    public void setBucketName(String name) { this.bucketName = name; }
    public String getAccessKeyId() { return accessKeyId; }
    public void setAccessKeyId(String id) { this.accessKeyId = id; }
    public String getAccessKeySecret() { return accessKeySecret; }
    public void setAccessKeySecret(String secret) { this.accessKeySecret = secret; }
    public String getStsRoleArn() { return stsRoleArn; }
    public void setStsRoleArn(String arn) { this.stsRoleArn = arn; }
    public String getResourcePrefix() { return resourcePrefix; }
    public String getThumbnailPrefix() { return thumbnailPrefix; }
    public int getTempFileExpireDays() { return tempFileExpireDays; }
}

/**
 * Elasticsearch配置
 *
 * ES集群部署，索引按学科/年级分片，
 * 支持IK中文分词器。
 */
class ElasticsearchConfig {

    /** ES集群节点列表 */
    private List<String> nodes;

    /** 连接超时（毫秒） */
    private int connectTimeout;

    /** 读取超时（毫秒） */
    private int socketTimeout;

    /** 索引名称 */
    private String indexName;

    /** 分片数 */
    private int shards;

    /** 副本数 */
    private int replicas;

    /** 用户名（X-Pack安全） */
    private String username;

    /** 密码 */
    private String password;

    public ElasticsearchConfig() {
        this.nodes = Arrays.asList("localhost:9200");
        this.connectTimeout = 5000;
        this.socketTimeout = 30000;
        this.indexName = "writech_resources";
        this.shards = 3;
        this.replicas = 1;
    }

    public List<String> getNodes() { return nodes; }
    public void setNodes(List<String> nodes) { this.nodes = nodes; }
    public int getConnectTimeout() { return connectTimeout; }
    public int getSocketTimeout() { return socketTimeout; }
    public String getIndexName() { return indexName; }
    public int getShards() { return shards; }
    public int getReplicas() { return replicas; }
    public String getUsername() { return username; }
    public void setUsername(String u) { this.username = u; }
    public String getPassword() { return password; }
    public void setPassword(String p) { this.password = p; }
}

/**
 * 资源安全服务
 *
 * 负责：
 * - 防盗链（Referer校验 + 签名URL）
 * - 数字水印（PDF/图片添加学校教师标识水印）
 * - 权限控制（按学校/区域授权）
 * - 点阵码安全（全局唯一分配防冲突）
 */
class ResourceSecurity {

    /** 防盗链Referer白名单 */
    private static final Set<String> REFERER_WHITELIST = new HashSet<>(Arrays.asList(
        "*.writech.com",
        "localhost"
    ));

    /**
     * 校验资源访问权限
     *
     * 规则：
     * - 管理员：可访问本校所有资源
     * - 教师：可访问本校已授权资源
     * - 学生/家长：仅可访问已分配的资源
     */
    public boolean checkPermission(
        String userId,
        String userRole,
        String userSchoolId,
        String resourceSchoolId
    ) {
        // 超级管理员无限制
        if ("super_admin".equals(userRole)) {
            return true;
        }

        // 校级管理员和教师：必须同校
        if ("admin".equals(userRole) || "teacher".equals(userRole)) {
            return userSchoolId != null && userSchoolId.equals(resourceSchoolId);
        }

        // 学生/家长：需要额外的资源分配记录校验
        // return resourceAssignmentMapper.isAssigned(userId, resourceId);
        return false;
    }

    /**
     * 验证Referer防盗链
     */
    public boolean validateReferer(String referer) {
        if (referer == null || referer.isEmpty()) {
            return false;
        }
        for (String pattern : REFERER_WHITELIST) {
            if (pattern.startsWith("*.")) {
                String domain = pattern.substring(2);
                if (referer.contains(domain)) return true;
            } else {
                if (referer.contains(pattern)) return true;
            }
        }
        return false;
    }

    /**
     * 生成水印文本
     * 格式：学校名称 + 教师姓名 + 日期
     */
    public String generateWatermarkText(
        String schoolName, String teacherName
    ) {
        String dateStr = new java.text.SimpleDateFormat("yyyy-MM-dd")
            .format(new Date());
        return String.format("%s %s %s", schoolName, teacherName, dateStr);
    }
}
