package de.hft.geotime.controllers;

import de.hft.geotime.entities.RecordType;
import de.hft.geotime.entities.TimeRecord;
import de.hft.geotime.entities.projections.RecordOverviewProjection;
import de.hft.geotime.repositories.RecordRepository;
import de.hft.geotime.repositories.TimetrackAccountRepository;
import org.springframework.data.projection.ProjectionFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Objects;

@RestController
public class RecordController {

    private final RecordRepository recordRepository;
    private final TimetrackAccountRepository accountRepository;
    private final ProjectionFactory projectionFactory;

    public RecordController(RecordRepository recordRepository, TimetrackAccountRepository accountRepository, ProjectionFactory projectionFactory) {
        this.recordRepository = recordRepository;
        this.accountRepository = accountRepository;
        this.projectionFactory = projectionFactory;
    }

    @GetMapping("/track")
    public ResponseEntity<RecordOverviewProjection> track(@RequestParam String account, Authentication authentication) {
        if (account == null || account.isEmpty()) {
            return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
        }

        var selectedAccount = accountRepository.findByUser_UsernameAndName(authentication.getName(), account);

        if (selectedAccount == null) {
            return new ResponseEntity<>(HttpStatus.NOT_FOUND);
        }

        var entires = recordRepository.findAllByEnddateIsNull(null);
        var collect = entires.get()
                .filter(Objects::nonNull)
                .filter(timeRecord -> selectedAccount.equals(timeRecord.getAccount()))
                .findFirst();

        var now = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss"));

        if (collect.isPresent()) {
            collect.get().setEnddate(LocalDateTime.parse(now));
            recordRepository.save(collect.get());
            var projection = projectionFactory.createProjection(RecordOverviewProjection.class, collect.get());
            return new ResponseEntity<>(projection, HttpStatus.OK);
        } else {
            var newRecord = new TimeRecord();
            newRecord.setType(RecordType.PAID);
            newRecord.setStartdate(LocalDateTime.parse(now));
            newRecord.setAccount(accountRepository.findByUser_UsernameAndName(authentication.getName(), account));
            recordRepository.save(newRecord);
            var projection = projectionFactory.createProjection(RecordOverviewProjection.class, newRecord);
            return new ResponseEntity<>(projection, HttpStatus.CREATED);
        }
    }
}
