package com.ecep.contract.cloud;

import static com.ecep.contract.SpringApp.getBean;

import java.math.BigDecimal;
import java.sql.Timestamp;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeParseException;
import java.util.Locale;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.function.Supplier;

import org.springframework.util.StringUtils;

import com.ecep.contract.MessageHolder;
import com.ecep.contract.ds.other.service.SysConfService;
import com.ecep.contract.util.MyStringUtils;
import com.ecep.contract.util.NumberUtils;

import lombok.Getter;
import lombok.Setter;

public class AbstractCtx {
    @Setter
    SysConfService confService;

    @Setter
    @Getter
    Locale locale = Locale.getDefault();

    public SysConfService getConfService() {
        if (confService == null) {
            confService = getBean(SysConfService.class);
        }
        return confService;
    }

    public boolean updateText(Supplier<String> getter, Consumer<String> setter, String text, MessageHolder holder,
            String topic) {
        if (!Objects.equals(getter.get(), text)) {
            setter.accept(text);
            holder.info(topic + "修改为: " + text);
            return true;
        }
        return false;
    }

    public boolean updateAppendText(Supplier<String> getter, Consumer<String> setter, String text, MessageHolder holder,
            String topic) {
        if (StringUtils.hasText(text)) {
            String str = MyStringUtils.appendIfAbsent(getter.get(), text);
            if (!Objects.equals(getter.get(), str)) {
                setter.accept(text);
                holder.info(topic + "修改为: " + text);
                return true;
            }
        }
        return false;
    }

    public boolean updateLocalDate(Supplier<LocalDate> getter, Consumer<LocalDate> setter, java.sql.Date date,
            MessageHolder holder, String topic) {
        if (date != null) {
            return updateLocalDate(getter, setter, date.toLocalDate(), holder, topic);
        }
        return false;
    }

    public boolean updateLocalDate(Supplier<LocalDate> getter, Consumer<LocalDate> setter, LocalDate date,
            MessageHolder holder, String topic) {
        return updateLocalDate(getter, setter, date, holder, topic, false);
    }

    public boolean updateLocalDate(Supplier<LocalDate> getter, Consumer<LocalDate> setter, LocalDate date,
            MessageHolder holder, String topic, boolean allowNull) {
        if (date == null && !allowNull) {
            return false;
        }
        if (!Objects.equals(getter.get(), date)) {
            setter.accept(date);
            holder.info(topic + "更新为 " + date);
            return true;
        }
        return false;
    }

    public boolean updateLocalDate(Supplier<LocalDate> getter, Consumer<LocalDate> setter, String strDate,
            MessageHolder holder, String topic) {
        LocalDate date = null;
        if (StringUtils.hasText(strDate)) {
            try {
                date = LocalDate.parse(strDate);
            } catch (DateTimeParseException e) {
                holder.warn("无法解析的日期:" + strDate);
            }
        }
        return updateLocalDate(getter, setter, date, holder, topic);
    }

    public boolean updateLocalDate(Supplier<LocalDate> getter, Consumer<LocalDate> setter, Timestamp timestamp,
            MessageHolder holder, String topic) {
        LocalDate date = null;

        if (timestamp != null) {
            try {
                date = timestamp.toLocalDateTime().toLocalDate();
            } catch (DateTimeParseException e) {
                holder.warn("解析日期" + timestamp + " 异常：" + e.getMessage());
            }
        }
        return updateLocalDate(getter, setter, date, holder, topic);
    }

    public boolean updateLocalDateTime(Supplier<LocalDateTime> getter, Consumer<LocalDateTime> setter,
            Timestamp timestamp, MessageHolder holder, String topic) {
        LocalDateTime dateTime = null;

        if (timestamp != null) {
            try {
                // fixed nanos
                timestamp.setNanos(0);
                dateTime = timestamp.toLocalDateTime();
            } catch (DateTimeParseException e) {
                holder.warn("解析日期" + timestamp + " 异常：" + e.getMessage());
            }
        }
        return updateLocalDateTime(getter, setter, dateTime, holder, topic);
    }

    public boolean updateLocalDateTime(Supplier<LocalDateTime> getter, Consumer<LocalDateTime> setter,
            LocalDateTime dateTime, MessageHolder holder, String topic) {
        if (!Objects.equals(getter.get(), dateTime)) {
            setter.accept(dateTime);
            holder.info(topic + "修改为: " + dateTime);
            return true;
        }
        return false;
    }

    public boolean updateInstant(Supplier<Instant> getter, Consumer<Instant> setter, Instant instant,
            MessageHolder holder, String topic) {
        if (!Objects.equals(getter.get(), instant)) {
            setter.accept(instant);
            holder.info(topic + "修改为: " + instant);
            return true;
        }
        return false;
    }

    public boolean updateNumber(Supplier<Double> getter, Consumer<Double> setter, BigDecimal value,
            MessageHolder holder, String topic) {
        double val = value.doubleValue();
        return updateNumber(getter, setter, val, holder, topic);
    }

    public boolean updateNumber(Supplier<Double> getter, Consumer<Double> setter, double value, MessageHolder holder,
            String topic) {
        if (getter.get() == null || !NumberUtils.equals(getter.get(), value)) {
            setter.accept(value);
            holder.info(topic + "修改为: " + value);
            return true;
        }
        return false;
    }

    public boolean updateNumber(Supplier<Float> getter, Consumer<Float> setter, float value, MessageHolder holder,
            String topic) {
        if (getter.get() == null || !NumberUtils.equals(getter.get(), value)) {
            setter.accept(value);
            holder.info(topic + "修改为: " + value);
            return true;
        }
        return false;
    }

    public boolean updateNumber(Supplier<Integer> getter, Consumer<Integer> setter, Integer value, MessageHolder holder,
            String topic) {
        if (getter.get() == null || !NumberUtils.equals(getter.get(), value)) {
            setter.accept(value);
            holder.info(topic + "修改为: " + value);
            return true;
        }
        return false;
    }
}
