package com.bio.bio_backend.domain.base.member.controller;

import com.bio.bio_backend.global.dto.ApiResponseDto;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import jakarta.validation.Valid;
import com.bio.bio_backend.domain.base.member.dto.MemberDto;
import com.bio.bio_backend.domain.base.member.dto.GetMemberResponseDto;
import com.bio.bio_backend.domain.base.member.dto.CreateMemberRequestDto;
import com.bio.bio_backend.domain.base.member.dto.CreateMemberResponseDto;

import com.bio.bio_backend.domain.base.member.dto.MemberSearchCondition;
import com.bio.bio_backend.domain.base.member.dto.GetMembersRequestDto;
import com.bio.bio_backend.domain.base.member.dto.GetMembersPagedRequestDto;
import com.bio.bio_backend.global.dto.PagedResult;
import com.bio.bio_backend.domain.base.member.service.MemberService;
import com.bio.bio_backend.domain.base.member.mapper.MemberMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import com.bio.bio_backend.global.constants.ApiResponseCode;
import com.bio.bio_backend.global.annotation.LogExecution;
import com.bio.bio_backend.global.utils.SecurityUtils;
import com.bio.bio_backend.global.utils.JwtUtils;
import jakarta.servlet.http.HttpServletResponse;


import java.util.List;


@Tag(name = "Member", description = "회원 관련 API")
@RestController
@RequestMapping("/members")
@RequiredArgsConstructor
@Slf4j
public class MemberController {

    private final MemberService memberService;
    private final MemberMapper memberMapper;
    private final JwtUtils jwtUtils;

    @LogExecution("회원 등록")
    @Operation(summary = "회원 등록", description = "새로운 회원을 등록합니다.")
    @ApiResponses({
        @ApiResponse(responseCode = "201", description = "회원 가입 성공"),
        @ApiResponse(responseCode = "400", description = "잘못된 요청 데이터", content = @Content),
        @ApiResponse(responseCode = "409", description = "중복된 사용자 정보", content = @Content)
    })
    @PostMapping("/register")
    public ResponseEntity<ApiResponseDto<CreateMemberResponseDto>> createMember(@RequestBody @Valid CreateMemberRequestDto requestDto) {
        MemberDto createdMember = memberService.createMember(memberMapper.toMemberDto(requestDto));
        CreateMemberResponseDto responseDto = memberMapper.toCreateMemberResponseDto(createdMember);
        ApiResponseDto<CreateMemberResponseDto> apiResponse = ApiResponseDto.success(ApiResponseCode.COMMON_SUCCESS_CREATED, responseDto);
        
        return ResponseEntity.status(HttpStatus.CREATED).body(apiResponse);
    }

    @LogExecution("회원 목록 조회")
    @Operation(summary = "회원 목록 조회", description = "활성화된 모든 회원의 목록을 조회합니다.")
    @ApiResponses({
        @ApiResponse(responseCode = "200", description = "회원 목록 조회 성공"),
        @ApiResponse(responseCode = "400", description = "잘못된 요청 파라미터", content = @Content)
    })
    @GetMapping
    public ResponseEntity<ApiResponseDto<List<GetMemberResponseDto>>> getMembers(@ModelAttribute GetMembersRequestDto requestDto) {
        MemberSearchCondition condition = memberMapper.toSearchCondition(requestDto);
        List<GetMemberResponseDto> members = memberService.getMembers(condition);
        ApiResponseDto<List<GetMemberResponseDto>> apiResponse = ApiResponseDto.success(ApiResponseCode.COMMON_SUCCESS, members);
        log.info("회원 목록 조회 완료: {}명", members.size());

        return ResponseEntity.ok(apiResponse);
    }

    @LogExecution("회원 목록 조회 (페이지네이션)")
    @Operation(summary = "회원 목록 조회 (페이지네이션)", description = "페이지네이션을 적용한 회원 목록을 조회합니다.")
    @ApiResponses({
        @ApiResponse(responseCode = "200", description = "회원 목록 조회 성공"),
        @ApiResponse(responseCode = "400", description = "잘못된 요청 파라미터", content = @Content)
    })
    @GetMapping("/paged")
    public ResponseEntity<ApiResponseDto<PagedResult<GetMemberResponseDto>>> getMembersPaged(@ModelAttribute GetMembersPagedRequestDto requestDto) {
        MemberSearchCondition condition = memberMapper.toSearchCondition(requestDto);
        PagedResult<GetMemberResponseDto> pagedMembers = memberService.getMembersPaged(condition, requestDto.getPage(), requestDto.getSize());
        ApiResponseDto<PagedResult<GetMemberResponseDto>> apiResponse = ApiResponseDto.success(ApiResponseCode.COMMON_SUCCESS, pagedMembers);
        log.info("페이지네이션된 회원 목록 조회 완료: 페이지={}, 크기={}, 전체={}명", requestDto.getPage(), requestDto.getSize(), pagedMembers.getTotalElements());

        return ResponseEntity.ok(apiResponse);
    }

    @LogExecution("로그아웃")
    @Operation(summary = "로그아웃", description = "사용자 로그아웃을 처리합니다.")
    @ApiResponses({
        @ApiResponse(responseCode = "200", description = "로그아웃 성공")
    })
    @PostMapping("/logout")
    public ResponseEntity<ApiResponseDto<Void>> logout(HttpServletResponse response) {
        String userId = SecurityUtils.getCurrentUserId();
        memberService.deleteRefreshToken(userId);
        // 모든 토큰 쿠키 삭제
        jwtUtils.deleteAllTokenCookies(response);
        log.info("사용자 로그아웃 완료: {}", userId);

        return ResponseEntity.ok(ApiResponseDto.success(ApiResponseCode.COMMON_SUCCESS));
    }
}
