package com.dbnt.faisp.main.faStatistics.crackdownsStatus.service;


import com.dbnt.faisp.config.BaseService;
import com.dbnt.faisp.main.faStatistics.crackdownsStatus.mapper.SailorMapper;
import com.dbnt.faisp.main.faStatistics.crackdownsStatus.model.crackdownStatus.CrackdownStatus;
import com.dbnt.faisp.main.faStatistics.crackdownsStatus.model.fishingBoat.FishingBoat;
import com.dbnt.faisp.main.faStatistics.crackdownsStatus.model.fishingBoat.Violation;
import com.dbnt.faisp.main.faStatistics.crackdownsStatus.model.sailor.Sailor;
import com.dbnt.faisp.main.faStatistics.crackdownsStatus.model.sailor.SailorVersion;
import com.dbnt.faisp.main.faStatistics.crackdownsStatus.repository.*;
import com.dbnt.faisp.util.Utils;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
@RequiredArgsConstructor
public class SailorService extends BaseService {

    private final SailorMapper sailorMapper;
    private final CrackdownStatusRepository crackdownStatusRepository;
    private final FishingBoatRepository fishingBoatRepository;
    private final ViolationRepository violationRepository;
    private final ProcessResultRepository processResultRepository;
    private final SailorRepository sailorRepository;
    private final SailorVersionRepository sailorVersionRepository;

    public List<Sailor> selectSailorList(Sailor sailor) {
        return sailorMapper.selectSailorList(sailor);
    }

    public Sailor selectSailor(Integer sailorKey) {
        return sailorRepository.findById(sailorKey).orElse(null);
    }

    public List<SailorVersion> selectSailorVersionList(Integer sailorKey) {
        return sailorVersionRepository.findBySailorKey(sailorKey);
    }

    public SailorVersion selectSailorVersion(Integer versionNo, Integer sailorKey) {
        return sailorVersionRepository.findByVersionNoAndSailorKey(versionNo, sailorKey);
    }

    @Transactional
    public Integer saveSailor(Sailor sailor) {
        if (sailor.getCrackdownStatus().getViolationDeleteKeyList() != null) {
            violationRepository.deleteAllByIdInQuery(sailor.getCrackdownStatus().getViolationDeleteKeyList());
        }
        Integer sailorKey = 0;
        Sailor existingSailor = sailorRepository.findBySailorKey(sailor.getSailorKey());

        if (existingSailor != null) {
            Utils.copyNonNullProperties(sailor, existingSailor);
            existingSailor.setViolationList(null);
            sailorKey = sailorRepository.save(existingSailor).getSailorKey();
            saveSailorVersion(existingSailor);
        } else {
            sailorKey = sailorRepository.save(sailor).getSailorKey();
            saveSailorVersion(sailor);
        }

        if (sailor.getCrackdownStatus() != null) {
            if (sailor.getCrackdownStatus().getCrackdownPoliceEtc() != null) {
                sailor.getCrackdownStatus().setCrackdownPolice(sailor.getCrackdownStatus().getCrackdownPoliceEtc());
            }

            CrackdownStatus existingCrackdownStatus = crackdownStatusRepository.findByCdsKey(sailor.getCrackdownStatus().getCdsKey()).orElse(null);
            Utils.copyNonNullProperties(sailor, existingCrackdownStatus);
            sailor.setCrackdownStatus(crackdownStatusRepository.save(existingCrackdownStatus));
        }

        if (sailor.getFishingBoat() != null) {
            FishingBoat existingFishingBoat = fishingBoatRepository.findByCdsKey(sailor.getCrackdownStatus().getCdsKey()).orElse(null);
            Utils.copyNonNullProperties(sailor, existingFishingBoat);
            fishingBoatRepository.save(existingFishingBoat);
        }

        if (sailor.getViolationList() != null && sailor.getViolationList().get(0).getViolation() != null) {
            Violation lastViolation = violationRepository.findTopByFbKeyOrderByViolationKeyDesc(sailor.getCrackdownStatus().getFbKey()).orElse(null);
            int violationKey = lastViolation==null?1:(lastViolation.getViolationKey()+1);

            for(Violation violation: sailor.getViolationList()){
                if (violation.getViolationEtc() != null) {
                    violation.setViolation(violation.getViolationEtc());
                }
                violation.setFbKey(sailor.getFishingBoat().getFbKey());
                if (violation.getViolationKey() == null) {
                    violation.setViolationKey(violationKey);
                    violationKey++;
                }
            }
            violationRepository.saveAll(sailor.getViolationList());
        }

        return sailorKey;
    }

    public void saveSailorVersion(Sailor sailor) {
        SailorVersion lastVersion = sailorVersionRepository.findTopBySailorKeyOrderByVersionNoDesc(sailor.getSailorKey()).orElse(null);
        int versionNo = lastVersion==null?1:(lastVersion.getVersionNo()+1);

        SailorVersion sailorVersion = new SailorVersion();
        BeanUtils.copyProperties(sailor, sailorVersion);
        sailorVersion.setVersionNo(versionNo);

        sailorVersionRepository.save(sailorVersion);
    }
}
