SET search_path TO library, public;

-- 清理可能存在的旧数据（可选，测试时方便重跑）
-- 请注意，CASCADE 会删除关联数据，请谨慎在生产环境使用
DELETE FROM fines;
DELETE FROM reviews;
DELETE FROM reservations;
DELETE FROM borrow_records;
DELETE FROM admins;
DELETE FROM students;
DELETE FROM books;
DELETE FROM system_settings WHERE setting_key NOT IN ('fine_per_day', 'freeze_threshold', 'max_borrow_default'); -- 保留核心设置

-- 0. 系统参数 (你已插入，这里可以补充更多，如果需要)
INSERT INTO system_settings(setting_key, setting_value) VALUES
('max_renew_times', '2'),            -- 最大续借次数
('borrow_duration_days', '30'),      -- 默认借阅时长（天）
('reservation_expiry_days', '3'),  -- 预约保留天数
('admin_default_password_hash', 'xxxx'); -- 示例：管理员默认密码哈希
-- ON CONFLICT (setting_key) DO UPDATE SET setting_value = EXCLUDED.setting_value; -- 如果要允许更新

-- 1. 管理员信息 (Admins)
INSERT INTO admins (emp_no, name, position, phone, privilege_lv) VALUES
('A001', '张管理', '馆长', '13800138000', 0),  -- 最高权限
('A002', '李协助', '图书管理员', '13900139000', 1),
('A003', '王登记', '流通部职员', '13700137000', 2);

-- 2. 图书信息 (Books)
-- 注意: available_copies 初始设为 total_copies，后续借阅会通过触发器减少
INSERT INTO books (isbn, title, authors, publisher, publish_date, price, classification_no, location, total_copies, available_copies, status, description, cover_url) VALUES
('9787111624927', '深入理解计算机系统', ARRAY['Randal E. Bryant', 'David R. O''Hallaron'], '机械工业出版社', '2019-05-01', 139.00, 'TP301', 'A区2架3层', 10, 10, 'normal', '计算机系统的经典之作。', 'http://example.com/cover1.jpg'),
('9787030598007', '数学之美', ARRAY['吴军'], '科学出版社', '2020-01-01', 68.00, 'O1', 'B区1架1层', 15, 15, 'normal', '通俗易懂的数学科普读物。', 'http://example.com/cover2.jpg'),
('9787544270878', '百年孤独', ARRAY['加西亚·马尔克斯'], '南海出版公司', '2011-06-01', 39.50, 'I775.45', 'C区5架2层', 8, 8, 'normal', '魔幻现实主义文学的代表作。', 'http://example.com/cover3.jpg'),
('9787115478850', 'Python编程：从入门到实践', ARRAY['Eric Matthes'], '人民邮电出版社', '2018-03-01', 89.00, 'TP312PY', 'A区3架1层', 12, 12, 'normal', 'Python入门畅销书。', 'http://example.com/cover4.jpg'),
('9787508647009', '人类简史：从动物到上帝', ARRAY['尤瓦尔·赫拉利'], '中信出版社', '2014-11-01', 68.00, 'K02', 'D区1架1层', 20, 20, 'normal', '一部宏大的人类发展史。', 'http://example.com/cover5.jpg'),
('9787532767406', '追风筝的人', ARRAY['卡勒德·胡赛尼'], '上海人民出版社', '2006-05-01', 29.00, 'I712.45', 'C区4架3层', 7, 7, 'normal', '关于爱、友谊、背叛和救赎的故事。', 'http://example.com/cover6.jpg'),
('9787121362308', 'Java核心技术 卷I', ARRAY['Cay S. Horstmann'], '电子工业出版社', '2019-06-01', 128.00, 'TP312JA', 'A区3架2层', 5, 0, 'normal', 'Java经典教材，目前全部被借出，用于测试预约。', 'http://example.com/cover7.jpg'), -- 特意设置 available_copies 为 0
('9787208159659', '三体全集', ARRAY['刘慈欣'], '重庆出版社', '2019-01-01', 168.00, 'I247.5', 'C区6架1层', 3, 3, 'damaged', '科幻巨作，其中一本有损坏。', 'http://example.com/cover8.jpg'),
('9787559620187', '明朝那些事儿 (套装全7册)', ARRAY['当年明月'], '北京联合出版公司', '2017-08-01', 258.00, 'K248', 'D区2架1层', 6, 6, 'normal', '通俗易懂的明史。', 'http://example.com/cover9.jpg'),
('9787111600815', '算法导论 (原书第3版)', ARRAY['Thomas H. Cormen'], '机械工业出版社', '2012-12-01', 128.00, 'TP301.6', 'A区2架4层', 9, 9, 'normal', '算法领域的圣经。', 'http://example.com/cover10.jpg'),
('9780132350884', 'Clean Code', ARRAY['Robert C. Martin'], 'Prentice Hall', '2008-08-01', 50.00, 'TP311.1', 'A区1架5层', 4, 4, 'removed', '一本已下架的书，测试状态。', 'http://example.com/cover11.jpg');


-- 3. 学生信息 (Students)
-- max_borrow 使用默认值（通过 get_setting_int('max_borrow_default') 获取，即10）
-- current_borrow 初始为0，会由触发器更新
INSERT INTO students (stu_no, name, gender, department, major, grade, class, phone, email, account_status) VALUES
('S2023001', '张三', 'M', '计算机学院', '软件工程', '2023', '01班', '13512345671', 'zhangsan@example.com', 'active'),
('S2023002', '李四', 'F', '计算机学院', '人工智能', '2023', '02班', '13512345672', 'lisi@example.com', 'active'),
('S2022003', '王五', 'M', '外国语学院', '英语', '2022', '01班', '13512345673', 'wangwu@example.com', 'active'),
('S2021004', '赵六', 'F', '经济管理学院', '工商管理', '2021', '03班', '13512345674', 'zhaoliu@example.com', 'active'),
('S2023005', '孙七', 'M', '计算机学院', '软件工程', '2023', '01班', '13512345675', 'sunqi@example.com', 'reported'), -- 测试挂失状态
('S2022006', '周八', 'F', '人文学院', '历史学', '2022', '02班', '13512345676', 'zhouba@example.com', 'active'),
('S2021007', '吴九', 'M', '理学院', '数学与应用数学', '2021', '01班', '13512345677', 'wujiu@example.com', 'active'),
('S2023008', '郑十', 'F', '计算机学院', '网络工程', '2023', '03班', '13512345678', 'zhengshi@example.com', 'active');

-- 修改一个学生的 max_borrow，测试非默认值
UPDATE students SET max_borrow = 15 WHERE stu_no = 'S2023001';
UPDATE students SET max_borrow = 5 WHERE stu_no = 'S2021004'; -- 用于测试借阅上限

-- 4. 借阅记录 (Borrow Records)
-- book_id 和 student_id 需要引用已存在的 ID
-- due_date = borrow_date + (SELECT setting_value::int FROM system_settings WHERE setting_key = 'borrow_duration_days')
-- fine_amount 初始为0, 逾期归还将由触发器在 fines 表中记录罚款
-- 触发器 trg_sync_book_student 会在每次插入/更新/删除后执行

-- 获取 book_id 和 student_id 的示例 (实际使用时，你可能需要根据书名/学号查询得到)
-- SELECT book_id FROM books WHERE isbn = '9787111624927'; -- 1
-- SELECT student_id FROM students WHERE stu_no = 'S2023001'; -- 1

-- 借阅场景 1: 正常借出，未到期
INSERT INTO borrow_records (book_id, student_id, borrow_date, due_date, status) VALUES
(1, 1, current_date - interval '10 days', current_date - interval '10 days' + interval '30 days', 'borrowed'), -- 张三借《深入理解计算机系统》
(2, 2, current_date - interval '5 days', current_date - interval '5 days' + interval '30 days', 'borrowed');  -- 李四借《数学之美》

-- 借阅场景 2: 正常借出，今天到期
INSERT INTO borrow_records (book_id, student_id, borrow_date, due_date, status) VALUES
(3, 1, current_date - interval '30 days', current_date, 'borrowed'); -- 张三借《百年孤独》，今天到期

-- 借阅场景 3: 已逾期，未归还
INSERT INTO borrow_records (book_id, student_id, borrow_date, due_date, status) VALUES
(4, 3, current_date - interval '40 days', current_date - interval '10 days', 'overdue'); -- 王五借《Python编程》，已逾期10天

-- 借阅场景 4: 正常归还 (触发器 trg_calc_fine 不会产生罚款)
INSERT INTO borrow_records (book_id, student_id, borrow_date, due_date, return_date, status) VALUES
(5, 4, current_date - interval '20 days', current_date + interval '10 days', current_date - interval '2 days', 'returned'); -- 赵六借《人类简史》，已按时归还

-- 借阅场景 5: 逾期归还 (为了测试 trg_calc_fine，先插入为逾期，再UPDATE为归还)
-- 步骤A: 先插入一条记录，状态为 'overdue' (或者 'borrowed' 但实际已过 due_date)
INSERT INTO borrow_records (book_id, student_id, borrow_date, due_date, status)
VALUES (6, 5, current_date - interval '35 days', current_date - interval '5 days', 'overdue'); -- 孙七借《追风筝的人》
-- 记录下这条 borrow_id (假设是 6，根据实际情况调整)
-- 步骤B: 更新这条记录为 'returned'，这将触发 trg_calc_fine
-- UPDATE borrow_records
-- SET status = 'returned', return_date = current_date
-- WHERE borrow_id = (SELECT borrow_id FROM borrow_records WHERE student_id=5 AND book_id=6 AND status='overdue');
-- (该update放到下面演示触发器部分)

-- 借阅场景 6: 书籍遗失
INSERT INTO borrow_records (book_id, student_id, borrow_date, due_date, status) VALUES
(9, 6, current_date - interval '15 days', current_date + interval '15 days', 'lost'); -- 周八借《明朝那些事儿》，遗失


-- 5. 图书预约 (Reservations)
-- 只能预约 available_copies = 0 的书
-- (book_id=7, 'Java核心技术 卷I', available_copies 初始为0)
INSERT INTO reservations (book_id, student_id, reserve_date, status) VALUES
(7, 1, current_date - interval '2 days', 'waiting'), -- 张三预约《Java核心技术》
(7, 2, current_date - interval '1 day', 'waiting');   -- 李四预约《Java核心技术》

-- 假设一本被预约的书有归还了，管理员将其状态改为可取
-- UPDATE reservations SET status = 'available' WHERE book_id = 7 AND student_id = 1;

-- 6. 图书评价 (Reviews)
-- 学生通常评价已借阅过的书
INSERT INTO reviews (book_id, student_id, rating, content, review_time) VALUES
(5, 4, 5, '《人类简史》这本书太棒了，视角独特，值得一读！', now() - interval '1 day'), -- 赵六评价《人类简史》
(1, 1, 4, '《深入理解计算机系统》有点难，但很有收获。', now()), -- 张三评价
(2, 2, 5, '《数学之美》让我对数学有了新的认识。', now()); -- 李四评价

-- 尝试插入重复评价（应失败，因为有UNIQUE约束）
-- INSERT INTO reviews (book_id, student_id, rating, content, review_time) VALUES
-- (5, 4, 3, '第二次评价，内容一般。', now());

-- 7. 罚款记录 (Fines)
-- 部分罚款会由 trg_calc_fine 自动生成 (当逾期借阅记录更新为 'returned' 时)
-- 手动添加一些罚款记录：

-- 罚款场景1: 图书损坏 (假设管理员A002处理)
INSERT INTO fines (student_id, amount, reason, status, issue_date, admin_id) VALUES
( (SELECT student_id FROM students WHERE stu_no = 'S2022003'), -- 王五
  20.00,
  '损坏图书《Python编程》(ISBN:9787115478850)',
  'unpaid',
  current_date - interval '1 day',
  (SELECT admin_id FROM admins WHERE emp_no = 'A002')
);

-- 罚款场景2: 图书遗失 (假设管理员A002处理)
-- 对应 borrow_records 中周八遗失的《明朝那些事儿》
INSERT INTO fines (student_id, amount, reason, status, issue_date, admin_id) VALUES
( (SELECT student_id FROM students WHERE stu_no = 'S2022006'), -- 周八
  (SELECT price FROM books WHERE isbn = '9787559620187'), -- 按书价赔偿
  '遗失图书《明朝那些事儿》(ISBN:9787559620187)',
  'unpaid',
  current_date,
  (SELECT admin_id FROM admins WHERE emp_no = 'A002')
);

-- 罚款场景3: 之前的逾期罚款，已缴纳
INSERT INTO fines (student_id, amount, reason, status, issue_date, admin_id) VALUES
( (SELECT student_id FROM students WHERE stu_no = 'S2021007'), -- 吴九
  5.50,
  '图书逾期11天 (旧记录)',
  'paid',
  current_date - interval '60 days',
  (SELECT admin_id FROM admins WHERE emp_no = 'A003')
);


----------------------------------------------------
-- 测试触发器 trg_calc_fine 和 trg_freeze_account
----------------------------------------------------
DO $$
DECLARE
    v_student_id_sunqi bigint;
    v_borrow_id_sunqi bigint;
    v_fine_per_day numeric;
    v_days_overdue int;
    v_expected_fine numeric;
BEGIN
    -- 获取孙七的 student_id
    SELECT student_id INTO v_student_id_sunqi FROM students WHERE stu_no = 'S2023005';
    -- 获取孙七之前插入的逾期借阅记录 (book_id=6, 追风筝的人)
    SELECT borrow_id INTO v_borrow_id_sunqi
    FROM borrow_records
    WHERE student_id = v_student_id_sunqi AND book_id = (SELECT book_id FROM books WHERE isbn='9787532767406') AND status = 'overdue';

    RAISE NOTICE '孙七(ID:%)的借阅记录ID: % 将被更新为已归还。', v_student_id_sunqi, v_borrow_id_sunqi;

    -- 模拟孙七归还之前逾期的书 (book_id=6, 《追风筝的人》)
    -- 这将触发 trg_calc_fine
    UPDATE borrow_records
    SET status = 'returned', return_date = current_date
    WHERE borrow_id = v_borrow_id_sunqi;

    RAISE NOTICE '已更新孙七的借阅记录。现在检查 fines 表是否自动产生罚款记录...';
    -- trg_calc_fine 会根据 borrow_records 中的 due_date 和 return_date 计算罚款并插入 fines 表
    -- 假设罚款汇率是 0.5/天，逾期5天，罚款应为 2.50
    -- (current_date - (current_date - interval '5 days')) * 0.50
    SELECT setting_value::numeric INTO v_fine_per_day FROM system_settings WHERE setting_key = 'fine_per_day';
    SELECT (current_date - (SELECT due_date FROM borrow_records WHERE borrow_id = v_borrow_id_sunqi)) INTO v_days_overdue;
    v_expected_fine := v_days_overdue * v_fine_per_day;
    RAISE NOTICE '预期罚款金额: % * % = %', v_days_overdue, v_fine_per_day, v_expected_fine;

    -- 检查孙七的账户状态是否因为罚款超过阈值 (默认20) 而被冻结
    -- trg_freeze_account 会在 fines 表 INSERT/UPDATE/DELETE 后触发
    RAISE NOTICE '检查孙七账户是否因罚款自动冻结...';
    -- 如果孙七的罚款 (例如 2.50) 没有超过 freeze_threshold (默认20.00)，账户不会冻结。
    -- 我们再为孙七手动添加一笔大额罚款，使其总欠款超过阈值
    IF (SELECT sum(amount) FROM fines WHERE student_id = v_student_id_sunqi AND status = 'unpaid') < (SELECT setting_value::numeric FROM system_settings WHERE setting_key = 'freeze_threshold') THEN
        RAISE NOTICE '孙七当前未付罚款未达冻结阈值，为其添加一笔大额罚款...';
        INSERT INTO fines (student_id, amount, reason, status, issue_date, admin_id) VALUES
        (v_student_id_sunqi, 25.00, '严重损坏图书赔偿', 'unpaid', current_date, (SELECT admin_id FROM admins WHERE emp_no='A001'));
        RAISE NOTICE '已为孙七添加大额罚款，再次检查账户状态。';
    END IF;

END $$;
