package com.tourism.webadmin.app.website.controller;

import com.tourism.common.additional.config.ApplicationConfig;
import com.tourism.common.core.annotation.MyRequestBody;
import com.tourism.common.core.constant.ErrorCodeEnum;
import com.tourism.common.core.object.MyRelationParam;
import com.tourism.common.core.object.ResponseResult;
import com.tourism.common.core.object.TokenData;
import com.tourism.common.core.upload.BaseUpDownloader;
import com.tourism.common.core.upload.UpDownloaderFactory;
import com.tourism.common.core.upload.UploadResponseInfo;
import com.tourism.common.core.upload.UploadStoreInfo;
import com.tourism.common.core.util.MyCommonUtil;
import com.tourism.common.core.util.MyModelUtil;
import com.tourism.common.log.annotation.OperationLog;
import com.tourism.common.log.model.constant.SysOperationLogType;
import com.tourism.common.redis.cache.SessionCacheHelper;
import com.tourism.webadmin.app.website.dto.WebsiteTourUserDto;
import com.tourism.webadmin.back.model.TourUser;
import com.tourism.webadmin.back.service.TourUserService;
import com.tourism.webadmin.back.vo.TourUserVo;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;

/**
 * 门户网站用户管理操作控制器类。
 *
 * @author 吃饭睡觉
 * @date 2024-09-06
 */
@Tag(name = "门户用户管理管理接口")
@Slf4j
@RestController
@RequestMapping("/website/tourism/user")
public class TourismUserController {

    @Autowired
    private ApplicationConfig appConfig;
    @Autowired
    private SessionCacheHelper cacheHelper;
    @Autowired
    private UpDownloaderFactory upDownloaderFactory;
    @Autowired
    private TourUserService tourUserService;

    /**
     * 更新门户用户管理数据。
     *
     * @param dto 更新对象。
     * @return 应答结果对象。
     */
    @OperationLog(type = SysOperationLogType.UPDATE)
    @PostMapping("/update")
    public ResponseResult<Void> update(@RequestBody WebsiteTourUserDto dto) {
        String errorMessage = MyCommonUtil.getModelValidationError(dto, true);
        if (errorMessage != null) {
            return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
        }
        Long userId = TokenData.takeFromRequest().getUserId();
        TourUser tourUserModel = MyModelUtil.copyTo(dto, TourUser.class);
        tourUserModel.setUserId(userId);

        if (!tourUserService.updateById(tourUserModel)) {
            return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
        }
        return ResponseResult.success();
    }

    /**
     * 查看指定门户用户管理对象详情。
     *
     * @param
     * @return 应答结果对象，包含对象详情。
     */
    @GetMapping("/view")
    public ResponseResult<TourUserVo> view() {
        Long userId = TokenData.takeFromRequest().getUserId();
        TourUser tourUser = tourUserService.getByIdWithRelation(userId, MyRelationParam.full());
        if (tourUser == null) {
            return ResponseResult.error(ErrorCodeEnum.UNAUTHORIZED_LOGIN);
        }
        TourUserVo tourUserVo = MyModelUtil.copyTo(tourUser, TourUserVo.class);
        return ResponseResult.success(tourUserVo);
    }

    /**
     * 文件上传操作。
     *
     * @param fieldName  上传文件名。
     * @param asImage    是否作为图片上传。如果是图片，今后下载的时候无需权限验证。否则就是附件上传，下载时需要权限验证。
     * @param uploadFile 上传文件对象。
     */
    @OperationLog(type = SysOperationLogType.UPLOAD, saveResponse = false)
    @PostMapping("/upload")
    public void upload(
            @RequestParam String fieldName,
            @RequestParam Boolean asImage,
            @RequestParam("uploadFile") MultipartFile uploadFile) throws IOException {
        UploadStoreInfo storeInfo = MyModelUtil.getUploadStoreInfo(TourUser.class, fieldName);
        // 这里就会判断参数中指定的字段，是否支持上传操作。
        if (!storeInfo.isSupportUpload()) {
            ResponseResult.output(HttpServletResponse.SC_FORBIDDEN,
                    ResponseResult.error(ErrorCodeEnum.INVALID_UPLOAD_FIELD));
            return;
        }
        // 根据字段注解中的存储类型，通过工厂方法获取匹配的上传下载实现类，从而解耦。
        BaseUpDownloader upDownloader = upDownloaderFactory.get(storeInfo.getStoreType());
        UploadResponseInfo responseInfo = upDownloader.doUpload(null,
                appConfig.getUploadFileBaseDir(), TourUser.class.getSimpleName(), fieldName, asImage, uploadFile);
        if (Boolean.TRUE.equals(responseInfo.getUploadFailed())) {
            ResponseResult.output(HttpServletResponse.SC_FORBIDDEN,
                    ResponseResult.error(ErrorCodeEnum.UPLOAD_FAILED, responseInfo.getErrorMessage()));
            return;
        }
        cacheHelper.putSessionUploadFile(responseInfo.getFilename());

        // 修改返回值，改为url，然后更新到用户信息表
//        tourUserService.changeHeadImage(TokenData.takeFromRequest().getUserId(), responseInfo.getFileUrl());
        ResponseResult.output(ResponseResult.success(responseInfo));
    }
}
