package model;

import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.time.LocalDateTime;
import java.util.stream.Collectors;

public class DataManager {
    private static DataManager instance;
    private Map<String, Goods> goodsMap;
    private List<String> suppliers;
    private Map<String, Integer> inventory;
    private List<OperationLog> operationLogs;

    private DataManager() {
        goodsMap = new HashMap<>();
        suppliers = new ArrayList<>();
        inventory = new HashMap<>();
        operationLogs = new ArrayList<>();
        initializeData();
    }

    public static DataManager getInstance() {
        if (instance == null) {
            instance = new DataManager();
        }
        return instance;
    }

    private void initializeData() {
        // 电子产品类
        addGoodsWithStock("G001", "苹果手机", "iPhone 15", "台", 6999.00, "电子产品", 50);
        addGoodsWithStock("G002", "联想笔记本", "ThinkPad T14", "台", 5999.00, "电子产品", 30);
        addGoodsWithStock("G003", "华为平板", "MatePad Pro", "台", 3999.00, "电子产品", 40);
        addGoodsWithStock("G004", "戴尔显示器", "27寸 4K", "台", 2399.00, "电子产品", 25);

        // 办公家具类
        addGoodsWithStock("G005", "办公桌", "1.4米", "张", 799.00, "办公家具", 100);
        addGoodsWithStock("G006", "办公椅", "人体工学", "把", 599.00, "办公家具", 150);
        addGoodsWithStock("G007", "文件柜", "三层", "个", 459.00, "办公家具", 80);
        addGoodsWithStock("G008", "会议桌", "2.4米", "张", 1599.00, "办公家具", 20);

        // 办公用品类
        addGoodsWithStock("G009", "打印纸", "A4 70g", "箱", 89.00, "办公用品", 200);
        addGoodsWithStock("G010", "签字笔", "0.5mm黑色", "盒", 15.00, "办公用品", 500);
        addGoodsWithStock("G011", "订书机", "标准型", "个", 35.00, "办公用品", 300);
        addGoodsWithStock("G012", "文件夹", "A4蓝色", "个", 8.00, "办公用品", 1000);

        // 添加供应商
        suppliers.add("苹果官方旗舰店");
        suppliers.add("联想专卖店");
        suppliers.add("华为授权店");
        suppliers.add("戴尔官方店");
        suppliers.add("京东自营");
        suppliers.add("天猫超市");
        suppliers.add("办公伙伴专营店");
        suppliers.add("文具批发商");
        suppliers.add("家具城");
        suppliers.add("办公用品直营店");
    }


    private void addGoodsWithStock(String id, String name, String specification,
                                   String unit, double price, String category, int initialStock) {
        Goods goods = new Goods(id, name, specification, unit, price, category, initialStock, "");
        goodsMap.put(id, goods);
        inventory.put(id, initialStock);
    }

    public void addGoods(Goods goods) {
        goodsMap.put(goods.getId(), goods);
        if (!inventory.containsKey(goods.getId())) {
            inventory.put(goods.getId(), 0);
        }
    }

    public static List<InventoryReport> generateInventoryReport() {
        List<InventoryReport> reports = new ArrayList<>();

        // 数据库连接URL
        String url = "jdbc:sqlite:db/dbuml.db3";

        try (Connection conn = DriverManager.getConnection(url);
             Statement stmt = conn.createStatement();
             ResultSet rs = stmt.executeQuery("SELECT goods_id, goods_name, SUM(quantity) as total_quantity, supplier, remark FROM inbound_records GROUP BY goods_id")) {

            while (rs.next()) {
                String goodsId = rs.getString("goods_id");
                String goodsName = rs.getString("goods_name");
                int totalQuantity = rs.getInt("total_quantity");
                String supplier = rs.getString("supplier");
                String remark = rs.getString("remark");

                reports.add(new InventoryReport(goodsId, goodsName, totalQuantity, supplier, remark));
            }

        } catch (SQLException e) {
            e.printStackTrace();
        }

        return reports;
    }

    public Goods getGoods(String id) {
        return goodsMap.get(id);
    }

    public List<Goods> getAllGoods() {
        return new ArrayList<>(goodsMap.values());
    }

    public List<String> getSuppliers() {
        return new ArrayList<>(suppliers);
    }

    public int getStock(String goodsId) {
        return inventory.getOrDefault(goodsId, 0);
    }

    public void updateStock(String goodsId, int quantity) {
        inventory.put(goodsId, inventory.getOrDefault(goodsId, 0) + quantity);
    }

    public Map<String, Integer> getAllStock() {
        return new HashMap<>(inventory);
    }

    public void addOperationLog(String operationType, String operationTarget, String operator, String details) {
        String id = "LOG" + System.currentTimeMillis();
        OperationLog log = new OperationLog(id, operationType, operationTarget, 
                                          operator, LocalDateTime.now(), details);
        operationLogs.add(log);
    }

    public List<OperationLog> getOperationLogs() {
        return new ArrayList<>(operationLogs);
    }

    public List<OperationLog> getFilteredOperationLogs(LocalDateTime startDate, LocalDateTime endDate, String operationType) {
        return operationLogs.stream()
            .filter(log -> {
                boolean timeMatch = true;
                if (startDate != null && endDate != null) {
                    timeMatch = !log.getOperationTime().isBefore(startDate) && 
                               !log.getOperationTime().isAfter(endDate);
                }
                boolean typeMatch = "全部".equals(operationType) || 
                                  operationType.equals(log.getOperationType());
                return timeMatch && typeMatch;
            })
            .collect(Collectors.toList());
    }

    public void addGoodsToDatabase(Goods goods) {
        String url = "jdbc:sqlite:db/dbuml.db3";
        String sql = "INSERT INTO goods (id, name, specification, unit, price, category, quantity, remark, inbound_time, operator, supplier) " +
                "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
        try (Connection conn = DriverManager.getConnection(url);
             PreparedStatement pstmt = conn.prepareStatement(sql)) {

            pstmt.setString(1, goods.getId());
            pstmt.setString(2, goods.getName());
            pstmt.setString(3, goods.getSpecification());
            pstmt.setString(4, goods.getUnit());
            pstmt.setDouble(5, goods.getPrice());
            pstmt.setString(6, goods.getCategory());
            pstmt.setInt(7, goods.getQuantity());
            pstmt.setString(8, goods.getRemark());
            pstmt.setString(9, goods.getInboundTime().toString());
            pstmt.setString(10, goods.getOperator());
            pstmt.setString(11, goods.getSupplier());

            pstmt.executeUpdate();
            addGoods(goods); // 同步内存中的数据
            addOperationLog("新增", goods.getId(), "当前用户", "新增货物: " + goods.getName());
        } catch (SQLException e) {
            e.printStackTrace();
            showAlert("错误", "添加货物失败:" + e.getMessage());
        }
    }

    public void updateGoodsInDatabase(Goods goods) {
        String url = "jdbc:sqlite:db/dbuml.db3";
        String sql = "UPDATE goods SET name = ?, specification = ?, unit = ?, price = ?, category = ?, " +
                "quantity = ?, remark = ?, inbound_time = ?, operator = ?, supplier = ? WHERE id = ?";
        try (Connection conn = DriverManager.getConnection(url);
             PreparedStatement pstmt = conn.prepareStatement(sql)) {

            pstmt.setString(1, goods.getName());
            pstmt.setString(2, goods.getSpecification());
            pstmt.setString(3, goods.getUnit());
            pstmt.setDouble(4, goods.getPrice());
            pstmt.setString(5, goods.getCategory());
            pstmt.setInt(6, goods.getQuantity());
            pstmt.setString(7, goods.getRemark());
            pstmt.setString(8, goods.getInboundTime().toString());
            pstmt.setString(9, goods.getOperator());
            pstmt.setString(10, goods.getSupplier());
            pstmt.setString(11, goods.getId());

            pstmt.executeUpdate();
            addOperationLog("更新", goods.getId(), "当前用户", "更新货物: " + goods.getName());
        } catch (SQLException e) {
            e.printStackTrace();
            showAlert("错误", "更新货物失败:" + e.getMessage());
        }
    }

    private void showAlert(String 错误, String s) {
    }


}