package com.example.demo.supplier.service;

import com.example.demo.supplier.dto.SupplierDtos;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class SupplierService {

    private final JdbcTemplate jdbcTemplate;

    public SupplierService(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    public Map<String, Object> search(Long shopId, String kw, boolean debtOnly, int page, int size) {
        StringBuilder sql = new StringBuilder("SELECT id,name,contact_name,mobile,phone,address,ap_opening,ap_payable,remark FROM suppliers WHERE shop_id=? AND status=1");
        java.util.List<Object> ps = new java.util.ArrayList<>();
        ps.add(shopId);
        if (kw != null && !kw.isBlank()) {
            sql.append(" AND (name LIKE ? OR phone LIKE ? OR mobile LIKE ?)");
            String like = '%'+kw+'%';
            ps.add(like); ps.add(like); ps.add(like);
        }
        if (debtOnly) {
            sql.append(" AND ap_payable > 0");
        }
        sql.append(" ORDER BY id DESC LIMIT ? OFFSET ?");
        ps.add(size); ps.add(Math.max(0, page) * size);
        List<Map<String,Object>> rows = jdbcTemplate.queryForList(sql.toString(), ps.toArray());
        List<SupplierDtos.SupplierListItem> items = rows.stream().map(r -> new SupplierDtos.SupplierListItem(
                ((Number)r.get("id")).longValue(),
                (String) r.get("name"),
                (String) r.get("contact_name"),
                (String) r.get("mobile"),
                (String) r.get("phone"),
                (String) r.get("address"),
                toBig((java.lang.Number) r.get("ap_opening")),
                toBig((java.lang.Number) r.get("ap_payable")),
                (String) r.get("remark")
        )).collect(Collectors.toList());
        java.util.Map<String,Object> resp = new java.util.HashMap<>();
        resp.put("list", items);
        return resp;
    }

    @Transactional
    public Long create(Long shopId, Long userId, SupplierDtos.CreateOrUpdateSupplierRequest req) {
        BigDecimal open = nz(req.apOpening);
        BigDecimal payable = nz(req.apPayable);
        String sql = "INSERT INTO suppliers (shop_id,user_id,name,contact_name,mobile,phone,address,status,ap_opening,ap_payable,remark,created_at,updated_at) " +
                "VALUES (?,?,?,?,?,?,?,?,?,?,?,NOW(),NOW())";
        org.springframework.jdbc.support.GeneratedKeyHolder kh = new org.springframework.jdbc.support.GeneratedKeyHolder();
        jdbcTemplate.update(con -> {
            java.sql.PreparedStatement ps = con.prepareStatement(sql, new String[]{"id"});
            int i = 1;
            ps.setLong(i++, shopId);
            ps.setLong(i++, userId);
            ps.setString(i++, req.name);
            ps.setString(i++, req.contactName);
            ps.setString(i++, req.mobile);
            ps.setString(i++, req.phone);
            ps.setString(i++, req.address);
            ps.setInt(i++, 1);
            ps.setBigDecimal(i++, open);
            ps.setBigDecimal(i++, payable);
            ps.setString(i, req.remark);
            return ps;
        }, kh);
        Number key = kh.getKey();
        return key == null ? null : key.longValue();
    }

    @Transactional
    public void update(Long id, Long shopId, Long userId, SupplierDtos.CreateOrUpdateSupplierRequest req) {
        String sql = "UPDATE suppliers SET name=?, contact_name=?, mobile=?, phone=?, address=?, ap_opening=?, ap_payable=?, remark=?, updated_at=NOW() WHERE id=? AND shop_id=?";
        jdbcTemplate.update(sql, req.name, req.contactName, req.mobile, req.phone, req.address, nz(req.apOpening), nz(req.apPayable), req.remark, id, shopId);
    }

    public java.util.Optional<java.util.Map<String,Object>> findById(Long id) {
        List<Map<String,Object>> rows = jdbcTemplate.queryForList("SELECT id,name,contact_name,mobile,phone,address,ap_opening,ap_payable,remark FROM suppliers WHERE id=?", id);
        if (rows.isEmpty()) return java.util.Optional.empty();
        return java.util.Optional.of(rows.get(0));
    }

    private static BigDecimal toBig(Number n) { return n == null ? BigDecimal.ZERO : new BigDecimal(n.toString()); }
    private static BigDecimal nz(BigDecimal v) { return v == null ? BigDecimal.ZERO : v.setScale(2, java.math.RoundingMode.HALF_UP); }
}


