package com.interplug.qcast.batch.estimate;

import com.fasterxml.jackson.core.type.TypeReference;
import com.interplug.qcast.biz.estimate.EstimateService;
import com.interplug.qcast.biz.estimate.dto.PlanSyncResponse;
import com.interplug.qcast.util.InterfaceQsp;
import java.util.Collections;
import java.util.List;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecutionListener;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.StepScope;
import org.springframework.batch.core.job.builder.JobBuilder;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.step.builder.StepBuilder;
import org.springframework.batch.item.ItemProcessor;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.support.ListItemReader;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.transaction.PlatformTransactionManager;

/** Plan 확정 Item 마스터 동기화 배치 */
@Configuration
public class PlanConfrimConfiguration implements JobExecutionListener {
  private final EstimateService estimateService;

  private final InterfaceQsp interfaceQsp;

  List<PlanSyncResponse> planSyncList;

  @Value("${qsp.estimate-plan-confirm-batch-url}")
  private String qspInterfaceUrl;

  public PlanConfrimConfiguration(EstimateService estimateService, InterfaceQsp interfaceQsp) {
    this.estimateService = estimateService;
    this.interfaceQsp = interfaceQsp;
  }

  @Bean
  public Job planConfirmJob(JobRepository jobRepository, Step planConfirmStep) {
    return new JobBuilder("planConfirmJob", jobRepository).start(planConfirmStep).build();
  }

  @Bean
  public Step planConfirmStep(
      JobRepository jobRepository, PlatformTransactionManager transactionManager) throws Exception {
    return new StepBuilder("planConfirmStep", jobRepository)
        .<PlanSyncResponse, PlanSyncResponse>chunk(100, transactionManager)
        .reader(planConfirmReader())
        .processor(planConfirmProcessor())
        .writer(planConfirmWriter())
        .build();
  }

  @Bean
  @StepScope
  public ListItemReader<PlanSyncResponse> planConfirmReader() throws Exception {
    this.planSyncList =
        interfaceQsp.callApiData(
            HttpMethod.GET, qspInterfaceUrl, null, new TypeReference<List<PlanSyncResponse>>() {});
    return (planSyncList != null)
        ? new ListItemReader<>(planSyncList)
        : new ListItemReader<>(Collections.emptyList());
  }

  @Bean
  public ItemProcessor<PlanSyncResponse, PlanSyncResponse> planConfirmProcessor() {
    return item -> item;
  }

  @Bean
  public ItemWriter<PlanSyncResponse> planConfirmWriter() {
    return items -> {
      estimateService.setPlanConfirmSyncSave((List<PlanSyncResponse>) items.getItems());
    };
  }
}
