package cn.lihongjie.coal.syslog.service;

import cn.lihongjie.coal.base.dto.CommonQuery;
import cn.lihongjie.coal.base.dto.IdRequest;
import cn.lihongjie.coal.base.service.BaseService;
import cn.lihongjie.coal.common.Constants;
import cn.lihongjie.coal.common.Ctx;
import cn.lihongjie.coal.common.RequestUtils;
import cn.lihongjie.coal.ip.IpQueryService;
import cn.lihongjie.coal.loginUser.dto.LoginUserDto;
import cn.lihongjie.coal.loginUser.service.LoginUserService;
import cn.lihongjie.coal.syslog.dto.CreateSysLogDto;
import cn.lihongjie.coal.syslog.dto.SysLogDto;
import cn.lihongjie.coal.syslog.dto.UpdateSysLogDto;
import cn.lihongjie.coal.syslog.entity.SysLogEntity;
import cn.lihongjie.coal.syslog.mapper.SysLogMapper;
import cn.lihongjie.coal.syslog.repository.SysLogRepository;

import jakarta.annotation.PostConstruct;
import jakarta.servlet.http.HttpServletRequest;

import lombok.extern.slf4j.Slf4j;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.convert.ConversionService;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Slf4j
@Transactional
public
class SysLogService extends BaseService<SysLogEntity, SysLogRepository> {

    @Autowired SysLogRepository repository;

    @Autowired SysLogMapper mapper;
    @Autowired ConversionService conversionService;

    @PostConstruct
    public void init() {}

    public SysLogDto create(CreateSysLogDto request) {

        SysLogEntity entity = mapper.toEntity(request);

        this.repository.save(entity);
        return getById(entity.getId());
    }

    public SysLogDto update(UpdateSysLogDto request) {
        SysLogEntity entity = this.repository.get(request.getId());
        this.mapper.updateEntity(entity, request);

        this.repository.save(entity);

        return getById(entity.getId());
    }

    public void delete(IdRequest request) {

        this.repository.deleteAllById(request.getIds());
    }

    public SysLogDto getById(String id) {

        SysLogEntity entity = repository.get(id);

        return mapper.toDto(entity);
    }

    @Async
    public void saveSync(SysLogEntity entity) {

        super.save(entity);
    }

    public Page<SysLogDto> list(CommonQuery query) {

        Page<SysLogEntity> page =
                repository.findAll(
                        query.specification(conversionService),
                        PageRequest.of(
                                query.getPageNo(),
                                query.getPageSize(),
                                Sort.by(query.getOrders())));

        return page.map(this.mapper::toDto);
    }

    @Autowired IpQueryService ipQueryService;
    @Autowired LoginUserService loginUserService;

    public void saveSysLog(
            HttpServletRequest request, String module, String action, String message) {

        String sessionId = request.getHeader(Constants.HTTP_HEADER_TOKEN);
        SysLogEntity sysLogEntity = new SysLogEntity();
        sysLogEntity.setIp(RequestUtils.getIp(request));
        sysLogEntity.setModule(module);
        sysLogEntity.setAction(action);
        sysLogEntity.setMessage(message);
        sysLogEntity.setIpLocation(ipQueryService.query(sysLogEntity.getIp()));
        sysLogEntity.setUserAgent(RequestUtils.getUa(request));
        sysLogEntity.setTimeCost(0);
        sysLogEntity.setUrl(request.getRequestURI());
        sysLogEntity.setOptStatus("1");
        if (StringUtils.isNotEmpty(sessionId)) {

            try {

                LoginUserDto dto = loginUserService.getFromCache(sessionId);

                sysLogEntity.setCreateUserId(dto.getUser().getId());

                sysLogEntity.setOrganizationId(dto.getUser().getOrganizationId());

            } catch (Exception e) {

                log.warn("获取用户信息失败", e);
            }
        }

        Ctx.getContext().getBean(this.getClass()).saveSync(sysLogEntity);
    }
}
