package com.davos.assessment.project;

import com.davos.assessment.auth.UserPrincipal;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
import java.time.Instant;
import java.util.List;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api")
public class HomepageAppointmentController {
  private final HomepageAppointmentRepository appointmentRepository;
  private final ProjectAccessService projectAccessService;

  public HomepageAppointmentController(
      HomepageAppointmentRepository appointmentRepository,
      ProjectAccessService projectAccessService) {
    this.appointmentRepository = appointmentRepository;
    this.projectAccessService = projectAccessService;
  }

  @PostMapping("/appointments")
  @Transactional
  public AppointmentRow create(@Valid @RequestBody CreateAppointmentRequest request) {
    HomepageAppointment appointment = new HomepageAppointment();
    appointment.setName(clean(request.name()));
    appointment.setOrganization(clean(request.organization()));
    appointment.setPhone(clean(request.phone()));
    appointment.setWechat(clean(request.wechat()));
    appointment.setCity(clean(request.city()));
    appointment.setSourcePath(cleanOptional(request.sourcePath()));
    appointment.setCreatedAt(Instant.now());
    return AppointmentRow.from(appointmentRepository.save(appointment));
  }

  @GetMapping("/super/appointments")
  @Transactional(readOnly = true)
  public List<AppointmentRow> list(@AuthenticationPrincipal UserPrincipal principal) {
    projectAccessService.requirePlatformSuper(principal);
    return appointmentRepository.findAllByOrderByCreatedAtDesc().stream()
        .map(AppointmentRow::from)
        .toList();
  }

  private static String clean(String value) {
    return value == null ? "" : value.trim();
  }

  private static String cleanOptional(String value) {
    String cleaned = clean(value);
    return cleaned.isBlank() ? "/" : cleaned;
  }

  public record CreateAppointmentRequest(
      @NotBlank @Size(max = 120) String name,
      @NotBlank @Size(max = 200) String organization,
      @NotBlank @Size(max = 80) String phone,
      @NotBlank @Size(max = 120) String wechat,
      @NotBlank @Size(max = 120) String city,
      @Size(max = 200) String sourcePath) {}

  public record AppointmentRow(
      Long id,
      String name,
      String organization,
      String phone,
      String wechat,
      String city,
      String sourcePath,
      String createdAt) {
    static AppointmentRow from(HomepageAppointment appointment) {
      return new AppointmentRow(
          appointment.getId(),
          appointment.getName(),
          appointment.getOrganization(),
          appointment.getPhone(),
          appointment.getWechat(),
          appointment.getCity(),
          appointment.getSourcePath(),
          appointment.getCreatedAt().toString());
    }
  }
}
