package com.alterdekim.game.controller;

import com.alterdekim.game.config.ServerConfig;
import com.alterdekim.game.controller.result.async.*;
import com.alterdekim.game.entity.User;
import com.alterdekim.game.security.AuthenticationUtil;
import com.alterdekim.game.service.*;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.UUID;

@Slf4j
@RestController
public class AsyncController {

    @Autowired
    private MiniquestService miniquestService;

    @Autowired
    private PhoneMessageService phoneMessageService;

    @Autowired
    private PostcardService postcardService;

    @Autowired
    private PreloaderService preloaderService;

    @Autowired
    private PromotionBannerService promotionBannerService;

    @Autowired
    private PromotionService promotionService;

    @Autowired
    private UserService userService;

    @Autowired
    private ServerConfig serverConfig;

    @Autowired
    private OnlineStatusService onlineStatusService;

    @PostMapping("/async/Ping")
    @ResponseBody
    public ResponseEntity<String> ping() {
        User user = AuthenticationUtil.authProfile(userService).get();
        onlineStatusService.setOnlineFor(user.getId());
        return ResponseEntity.ok("<response isPong=\"true\" />");
    }

    @PostMapping("/async/ServerAction")
    @ResponseBody
    public ResponseEntity<String> serverAction() {
        try {
            User user = AuthenticationUtil.authProfile(userService).get();

            XmlMapper xmlMapper = new XmlMapper();
            xmlMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.NONE);
            xmlMapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
            ServerActionResult serverActionResult = new ServerActionResult();
            serverActionResult.setSnStatus(new SnStatus(false));
            serverActionResult.setUsername(new UserName(user.getUsername()));
            serverActionResult.setFlags(new Flags(true, 13));
            serverActionResult.setRequests(new Grants(0));
            serverActionResult.setGrants(new Grants(0));
            List<ConfigItem> items = new ArrayList<>();
            items.add(new ConfigItem(1, ServerActionConfigType.IsPreloaderEnabled, "1", "bool")); // play with it
            items.add(new ConfigItem(2, ServerActionConfigType.SynchronizeAvatarRotation, "1", "bool"));
            items.add(new ConfigItem(3, ServerActionConfigType.InitialVolumeValue, "30", "number"));
            items.add(new ConfigItem(4, ServerActionConfigType.IsStartupHomeLocation, "0", "bool"));
            items.add(new ConfigItem(5, ServerActionConfigType.AccessRoleFlags, "0", "number"));
            items.add(new ConfigItem(6, ServerActionConfigType.IsInternational, "0", "bool")); // play with it
            items.add(new ConfigItem(7, ServerActionConfigType.TypeWeapon, "1", "number"));
            items.add(new ConfigItem(8, ServerActionConfigType.StatisticsSendInterval, "300", "number"));
            items.add(new ConfigItem(9, ServerActionConfigType.SwfVersion, "", "string"));
            items.add(new ConfigItem(10, ServerActionConfigType.LanguageId, "1", "number")); // play with it
            items.add(new ConfigItem(11, ServerActionConfigType.SnId, "1", "number"));
            items.add(new ConfigItem(12, ServerActionConfigType.AutoServerSelectionAllowed, "0", "bool"));
            List<ServerItem> s_items = new ArrayList<>();
            s_items.add(new ServerItem(1, 202, 5, "rtmp://"+serverConfig.getPublicDomain()+":"+serverConfig.getGameServerPort()+"/shararam", 0, 1, 5, 5.1));

            serverActionResult.setPhone(new PhoneMessages(phoneMessageService.getAllByReceiverId(user.getId())));
            serverActionResult.setMiniquest(miniquestService.getAllMiniquests());
            serverActionResult.setPostcard(new PostcardMessages(postcardService.getAllPostcardsOfUser(user.getId())));
            serverActionResult.setPreloader(preloaderService.getSelected());
            serverActionResult.setPromotion(promotionService.getSelected());
            serverActionResult.setPromotionBanners(promotionBannerService.getSelected());


            List<Tutorial> tutorials = new ArrayList<>();
            tutorials.add(new Tutorial(-1, 1));
            tutorials.add(new Tutorial(1, 1));
            tutorials.add(new Tutorial(2, 1));
            tutorials.add(new Tutorial(3, 1));
            tutorials.add(new Tutorial(4, 1));
            tutorials.add(new Tutorial(5, 1));
            serverActionResult.setTutorial(tutorials);

            List<ServerActionCData> cdatas = new ArrayList<>();
            cdatas.add(new ServerActionConfig(items));
            cdatas.add(new ServerActionSystem(1, "cache/resources.swf")); // swf/cache/rus/resources[19].swf
            if( !user.getIsBanned() ) {
                cdatas.add(new ServerActionUser(user.getId(), AuthenticationUtil.getToken(user), AuthenticationUtil.getToken(user), 2, null, null));
                cdatas.add(new ServerActionServers(s_items));
            } else {
                cdatas.add(new ServerActionUser(user.getId(), null, null, 0, LocalDateTime.now(), 162L));
            }
            serverActionResult.setCdata(cdatas);
            return ResponseEntity.ok()
                    .contentType(MediaType.APPLICATION_XML)
                    .body(xmlMapper.writeValueAsString(serverActionResult));
        } catch (JsonProcessingException e) {
            log.error(e.getMessage(), e);
        }
        return ResponseEntity.noContent().build();
    }
}
