package com.davos.assessment.project;

import com.davos.assessment.auth.UserPrincipal;
import com.davos.assessment.common.ApiException;
import com.davos.assessment.user.AppUser;
import com.davos.assessment.user.UserRole;
import jakarta.servlet.http.HttpServletRequest;
import java.util.Optional;
import java.util.Set;
import java.util.regex.Pattern;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

@Service
public class ProjectAccessService {
  public static final String DEFAULT_PROJECT_SLUG = "davos";
  private static final Pattern SLUG_PATTERN = Pattern.compile("^[a-z0-9][a-z0-9-]{1,48}[a-z0-9]$");
  private static final Set<String> RESERVED_SLUGS = Set.of(
      "api", "super", "admin", "admin-legacy", "assets", "static", "favicon.svg", "health");

  private final ProjectRepository projectRepository;
  private final ProjectMembershipRepository membershipRepository;

  public ProjectAccessService(ProjectRepository projectRepository, ProjectMembershipRepository membershipRepository) {
    this.projectRepository = projectRepository;
    this.membershipRepository = membershipRepository;
  }

  public void validateSlug(String slug) {
    if (slug == null || !SLUG_PATTERN.matcher(slug).matches() || RESERVED_SLUGS.contains(slug)) {
      throw new ApiException(HttpStatus.BAD_REQUEST, "项目路径 slug 不合法");
    }
  }

  public Project findEnabledProject(String slug) {
    Project project = projectRepository.findBySlug(slug)
        .orElseThrow(() -> new ApiException(HttpStatus.NOT_FOUND, "项目不存在"));
    if (!project.isEnabled()) {
      throw new ApiException(HttpStatus.FORBIDDEN, "项目已停用");
    }
    return project;
  }

  public Project findProject(String slug) {
    return projectRepository.findBySlug(slug)
        .orElseThrow(() -> new ApiException(HttpStatus.NOT_FOUND, "项目不存在"));
  }

  public Project currentProjectOrDefault() {
    return findProject(currentSlugOrDefault());
  }

  public String currentSlugOrDefault() {
    ServletRequestAttributes attrs = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
    if (attrs == null) return DEFAULT_PROJECT_SLUG;
    HttpServletRequest request = attrs.getRequest();
    String uri = request.getRequestURI();
    String prefix = "/api/projects/";
    if (uri.startsWith(prefix)) {
      String rest = uri.substring(prefix.length());
      int slash = rest.indexOf('/');
      return slash >= 0 ? rest.substring(0, slash) : rest;
    }
    return DEFAULT_PROJECT_SLUG;
  }

  public Project requireProjectMember(String slug, UserPrincipal principal) {
    Project project = findEnabledProject(slug);
    requireMember(project, principal);
    return project;
  }

  public Project requireProjectParticipant(String slug, UserPrincipal principal) {
    Project project = findEnabledProject(slug);
    ProjectMembership membership = requireMember(project, principal);
    if (membership.getRole() != ProjectMembershipRole.PARTICIPANT
        && membership.getRole() != ProjectMembershipRole.PROJECT_ADMIN
        && !isPlatformSuper(principal.user())) {
      throw new ApiException(HttpStatus.FORBIDDEN, "当前账号没有该项目权限");
    }
    return project;
  }

  public Project requireProjectAdmin(String slug, UserPrincipal principal) {
    Project project = findEnabledProject(slug);
    if (principal == null) {
      throw new ApiException(HttpStatus.FORBIDDEN, "需要管理员权限");
    }
    if (isPlatformSuper(principal.user())) return project;
    ProjectMembership membership = requireMember(project, principal);
    if (membership.getRole() != ProjectMembershipRole.PROJECT_ADMIN) {
      throw new ApiException(HttpStatus.FORBIDDEN, "需要项目管理员权限");
    }
    return project;
  }

  public void requirePlatformSuper(UserPrincipal principal) {
    if (principal == null || !isPlatformSuper(principal.user())) {
      throw new ApiException(HttpStatus.FORBIDDEN, "需要平台超级管理员权限");
    }
  }

  public boolean isPlatformSuper(AppUser user) {
    return user != null && user.getRole().isPlatformSuper();
  }

  public Optional<ProjectMembership> membership(Project project, AppUser user) {
    if (project == null || user == null) return Optional.empty();
    return membershipRepository.findByProjectAndUser(project, user)
        .filter(ProjectMembership::isEnabled);
  }

  private ProjectMembership requireMember(Project project, UserPrincipal principal) {
    if (principal == null) {
      throw new ApiException(HttpStatus.FORBIDDEN, "需要项目权限");
    }
    if (isPlatformSuper(principal.user())) {
      ProjectMembership synthetic = new ProjectMembership();
      synthetic.setProject(project);
      synthetic.setUser(principal.user());
      synthetic.setRole(ProjectMembershipRole.PROJECT_ADMIN);
      synthetic.setEnabled(true);
      return synthetic;
    }
    return membership(project, principal.user())
        .orElseThrow(() -> new ApiException(HttpStatus.FORBIDDEN, "当前账号不属于该项目"));
  }
}
