package de.votian.services.controller;

import de.votian.services.dto.HeadquartersDetailDto;
import de.votian.services.dto.UserSessionDto;
import de.votian.services.entity.Address;
import de.votian.services.entity.Company;
import de.votian.services.entity.Headquarters;
import de.votian.services.security.AccessControlService;
import de.votian.services.service.HeadquartersService;
import de.votian.services.service.ViewDataService;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/api/headquarters")
public class HeadquartersController {

    private final HeadquartersService headquartersService;
    private final ViewDataService viewDataService;
    private final AccessControlService accessControlService;

    public HeadquartersController(HeadquartersService headquartersService,
                                  ViewDataService viewDataService,
                                  AccessControlService accessControlService) {
        this.headquartersService = headquartersService;
        this.viewDataService = viewDataService;
        this.accessControlService = accessControlService;
    }

    @GetMapping
    public ResponseEntity<List<Headquarters>> findAll(Authentication authentication) {
        UserSessionDto user = accessControlService.sessionUser(authentication);
        if (!accessControlService.canManageEmployees(user)) {
            return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
        }
        return ResponseEntity.ok(headquartersService.findAll().stream()
                .filter(headquarters -> accessControlService.canAccessHeadquarters(user, headquarters.getId()))
                .toList());
    }

    @GetMapping("/{id}")
    public ResponseEntity<HeadquartersDetailDto> findById(@PathVariable Long id, Authentication authentication) {
        UserSessionDto user = accessControlService.sessionUser(authentication);
        if (!accessControlService.canAccessHeadquarters(user, id)) {
            return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
        }
        return viewDataService.findHeadquartersDetail(id)
                .map(ResponseEntity::ok)
                .orElse(ResponseEntity.notFound().build());
    }

    @GetMapping("/{id}/company")
    public ResponseEntity<Company> getCompany(@PathVariable Long id, Authentication authentication) {
        UserSessionDto user = accessControlService.sessionUser(authentication);
        if (!accessControlService.canAccessHeadquarters(user, id)) {
            return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
        }
        return headquartersService.getCompany(id)
                .map(ResponseEntity::ok)
                .orElse(ResponseEntity.notFound().build());
    }

    @PutMapping("/{id}")
    public ResponseEntity<HeadquartersDetailDto> update(@PathVariable Long id,
                                                        @RequestBody HeadquartersUpdateRequest request,
                                                        Authentication authentication) {
        UserSessionDto user = accessControlService.sessionUser(authentication);
        if (!accessControlService.canManageHeadquarters(user) || !accessControlService.canAccessHeadquarters(user, id)) {
            return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
        }
        headquartersService.updateHeadquarters(
                id,
                request.headquarters,
                request.company,
                request.address,
                request.bwvPhone,
                request.gln,
                request.duns
        );
        return viewDataService.findHeadquartersDetail(id)
                .map(ResponseEntity::ok)
                .orElse(ResponseEntity.notFound().build());
    }

    public static class HeadquartersUpdateRequest {
        public Headquarters headquarters;
        public Company company;
        public Address address;
        public String bwvPhone;
        public String gln;
        public String duns;
    }
}
