﻿// Copyright 2013-2022 AFI,Inc. All rights reserved

using System;
using System.Collections.Generic;
using UnityEngine;
using BackEnd;

public class GameDataGroup : BaseGroup {
    public override string GetGroupName() {
        return "게임 정보 관리";
    }

    public override void SetSubFunctionButton() {
        UIManager.Instance.AddSubFunction("전체 데이터 조회", GetTableList);
        
        UIManager.Instance.AddSubFunction("게임 정보 삽입", Insert);
        
        UIManager.Instance.AddSubFunction("inDate로 게임 정보 조회", GetV2ByInDate);
        UIManager.Instance.AddSubFunction("쿼리로 게임 정보 조회", GetByQuery);
        
        UIManager.Instance.AddSubFunction("inDate로 내 게임 정보 조회", GetMyDataV2ByInDate);
        UIManager.Instance.AddSubFunction("쿼리로 내 게임 정보 조회", GetMyDataByQuery);
        
        UIManager.Instance.AddSubFunction("inDate로 게임 정보 수정", UpdateWithInDate);
        UIManager.Instance.AddSubFunction("쿼리로 게임 정보 수정", UpdateWithQuery);
                
        UIManager.Instance.AddSubFunction("inDate로 게임 정보 연산", UpdateCalculationWithInDate);
        UIManager.Instance.AddSubFunction("쿼리로 게임 정보 연산", UpdateCalculationWithQuery);
        
        UIManager.Instance.AddSubFunction("inDate로 게임 정보 삭제", DeleteWithInDate);
        UIManager.Instance.AddSubFunction("쿼리로 게임 정보 삭제", DeleteWithQuery);
        
        UIManager.Instance.AddSubFunction("트랜잭션 쓰기", TransactionWrite);
        UIManager.Instance.AddSubFunction("트랜잭션 읽기", TransactionRead);
    }

    private void GetTableList() {
        requestUI.SetExecuteButtonAction( () => {
            var bro = Backend.GameData.GetTableList();
            ShowResultData(bro);
        });
    }

    private void Insert() {
        requestUI.AddInputField("테이블 이름");
        requestUI.SetExtraInputAddUI();

        requestUI.SetExecuteButtonAction( () => {
            var tableName = InputParseByString(0, 0);
            
            Param param = new Param();
            AddParamFromExtraInput(1, param);

            
            var bro = Backend.GameData.Insert(tableName, param);
            ShowResultData(bro);
        }); 
    }

    private void GetV2ByInDate() {
        requestUI.AddInputField("테이블 이름");
        requestUI.AddInputField("데이터 inDate");
        requestUI.AddInputField("유저 inDate");
        
        requestUI.SetExecuteButtonAction( () => {

            var tableName = InputParseByString(0, 0);
            var rowInDate = InputParseByString(1, 0);
            var userInDate = InputParseByString(2, 0);

            var bro = Backend.GameData.GetV2(tableName, rowInDate, userInDate);
            ShowResultData(bro); 
        });
    }

    private string _getV2FirstString = string.Empty;
    private void GetByQuery() {
        requestUI.AddInputField("테이블 이름");
        requestUI.AddInputField("불러올 갯수", 10);
        requestUI.AddInputField("다음 페이지 여부", "false");
        requestUI.AddInputField("내림(DESC)/오름(ASC)차순", "DESC");
        requestUI.AddInputField(new string[]{"검색할 컬럼(선택)", "검색할 값(Equal 조건)"});
        
        requestUI.SetExecuteButtonAction( () => {
            
            var tableName = InputParseByString(0, 0);
            var limit = InputParseByInt(1, 0);
            var nextPage = InputParseByBool(2, 0);
            var tableSortOrder = InputParseByEnum<TableSortOrder>(3, 0);

            Where where = new Where();

            string whereKey = InputParseByString(4, 0);
            string whereValue = InputParseByString(4, 1);

            if (!string.IsNullOrEmpty(whereKey) && !string.IsNullOrEmpty(whereValue)) {
                where.Equal(whereKey, whereValue);
            }

            BackendReturnObject bro;
            if (nextPage) {
                bro = Backend.GameData.Get(tableName, where, limit, string.Empty, tableSortOrder);
            } else {
                bro = Backend.GameData.Get(tableName, where, limit, _getV2FirstString, tableSortOrder);
            }
            
            if (bro.IsSuccess()) {
                if (bro.HasFirstKey()) {
                    _getV2FirstString = bro.FirstKeystring();
                } else {
                    _getV2FirstString = string.Empty;
                }
            }
            
            ShowResultData(bro); 
        });
    }
    
    private void GetMyDataV2ByInDate() {
        requestUI.AddInputField("테이블 이름");
        requestUI.AddInputField("데이터 inDate");
        
        requestUI.SetExecuteButtonAction( () => {

            var tableName = InputParseByString(0, 0);
            var rowInDate = InputParseByString(1, 0);

            var bro = Backend.GameData.GetMyData(tableName, rowInDate);
            ShowResultData(bro); 
        });
    }

    private string _getMyDataV2FirstString = string.Empty;
    private void GetMyDataByQuery() {
        requestUI.AddInputField("테이블 이름");
        requestUI.AddInputField("불러올 갯수", 10);
        requestUI.AddInputField("다음 페이지 여부", "false");

        requestUI.AddInputField(new string[]{"검색할 컬럼(선택)", "검색할 값(Equal 조건)"});
        
        requestUI.SetExecuteButtonAction( () => {
            
            var tableName = InputParseByString(0, 0);
            var limit = InputParseByInt(1, 0);
            var nextPage = InputParseByBool(2, 0);

            Where where = new Where();

            string whereKey = InputParseByString(3, 0);
            string whereValue = InputParseByString(3, 1);

            if (!string.IsNullOrEmpty(whereKey) && !string.IsNullOrEmpty(whereValue)) {
                where.Equal(whereKey, whereValue);
            }

            BackendReturnObject bro;
            if (nextPage) {
                bro = Backend.GameData.GetMyData(tableName, where, limit);
            } else {
                bro = Backend.GameData.GetMyData(tableName, where, limit, _getMyDataV2FirstString);
            }
            
            if (bro.IsSuccess()) {
                if (bro.HasFirstKey()) {
                    _getV2FirstString = bro.FirstKeystring();
                } else {
                    _getV2FirstString = string.Empty;
                }
            }
            
            ShowResultData(bro); 
        });
    }
    
    private void UpdateWithInDate() {
        requestUI.AddInputField("테이블 이름");
        requestUI.AddInputField("데이터 inDate");
        requestUI.AddInputField("유저 inDate");

        requestUI.SetExtraInputAddUI();

        requestUI.SetExecuteButtonAction( () => {
            var tableName = InputParseByString(0, 0);
            var rowInDate = InputParseByString(1, 0);
            var userInDate = InputParseByString(2, 0);

            Param param = new Param();
            AddParamFromExtraInput(3, param);

            
            var bro = Backend.GameData.UpdateV2(tableName, rowInDate,userInDate,param);
            ShowResultData(bro);
        }); 
    }
    
    private void UpdateWithQuery() {
        requestUI.AddInputField("테이블 이름");
        requestUI.AddInputField(new string[]{"검색할 컬럼(선택)", "검색할 값(Equal 조건)"});

        requestUI.SetExtraInputAddUI();

        requestUI.SetExecuteButtonAction( () => {
            var tableName = InputParseByString(0, 0);

            Where where = new Where();
            string whereKey = InputParseByString(1, 0);
            string whereValue = InputParseByString(1, 1);

            if (!string.IsNullOrEmpty(whereKey) && !string.IsNullOrEmpty(whereValue)) {
                where.Equal(whereKey, whereValue);
            }

            Param param = new Param();
            AddParamFromExtraInput(2, param);

            
            var bro = Backend.GameData.Update(tableName, where, param);
            ShowResultData(bro);
        }); 
    }
    
    private void UpdateCalculationWithInDate() {
        requestUI.AddInputField("테이블 이름");
        requestUI.AddInputField("데이터 inDate");
        requestUI.AddInputField("유저 inDate");

        requestUI.SetExtraInputAddUI(ExtraInputAddUI.ExtraInputType.CALCULATION);

        requestUI.SetExecuteButtonAction( () => {
            var tableName = InputParseByString(0, 0);

            var rowInDate = InputParseByString(1, 0);
            var userInDate = InputParseByString(2, 0);

            Param param = new Param();
            for (int i = 3; i < requestUI.GetValueInputFieldList().Count; i++) {
                string key = InputParseByString(i, 0);
                GameInfoOperator oper = InputParseByEnum<GameInfoOperator>(i, 1);
                float value = InputParseByFloat(i, 2);
                
                param.AddCalculation(key,oper,value);
            }
            
            var bro = Backend.GameData.UpdateWithCalculationV2(tableName, rowInDate, userInDate,param);
            ShowResultData(bro);
        }); 
    }
    
    private void UpdateCalculationWithQuery() {
        requestUI.AddInputField("테이블 이름");
        requestUI.AddInputField(new string[]{"검색할 컬럼(선택)", "검색할 값(Equal 조건)"});

        requestUI.SetExtraInputAddUI(ExtraInputAddUI.ExtraInputType.CALCULATION);

        requestUI.SetExecuteButtonAction( () => {
            var tableName = InputParseByString(0, 0);

            Where where = new Where();
            string whereKey = InputParseByString(1, 0);
            string whereValue = InputParseByString(1, 1);

            if (!string.IsNullOrEmpty(whereKey) && !string.IsNullOrEmpty(whereValue)) {
                where.Equal(whereKey, whereValue);
            }

            Param param = new Param();

            for (int i = 2; i < requestUI.GetValueInputFieldList().Count; i++) {
                string key = InputParseByString(i, 0);
                GameInfoOperator oper = InputParseByEnum<GameInfoOperator>(i, 1);
                float value = InputParseByFloat(i, 2);
                
                param.AddCalculation(key,oper,value);
            }
            
            var bro = Backend.GameData.UpdateWithCalculation(tableName, where, param);
            ShowResultData(bro);
        }); 
    }
    
    private void DeleteWithInDate() {
        requestUI.AddInputField("테이블 이름");
        requestUI.AddInputField("데이터 inDate");
        requestUI.AddInputField("유저 inDate");
        
        requestUI.SetExecuteButtonAction( () => {
            var tableName = InputParseByString(0, 0);
            var rowInDate = InputParseByString(1, 0);
            var userInDate = InputParseByString(2, 0);

            
            var bro = Backend.GameData.DeleteV2(tableName, rowInDate,userInDate);
            ShowResultData(bro);
        }); 
    }
    
    private void DeleteWithQuery() {
        requestUI.AddInputField("테이블 이름");
        requestUI.AddInputField(new string[]{"검색할 컬럼(선택)", "검색할 값(Equal 조건)"});
        
        requestUI.SetExecuteButtonAction( () => {
            var tableName = InputParseByString(0, 0);

            Where where = new Where();
            string whereKey = InputParseByString(1, 0);
            string whereValue = InputParseByString(1, 1);

            if (!string.IsNullOrEmpty(whereKey) && !string.IsNullOrEmpty(whereValue)) {
                where.Equal(whereKey, whereValue);
            }

            var bro = Backend.GameData.Delete(tableName, where);
            ShowResultData(bro);
        }); 
    }
    
    private void TransactionWrite() {
        requestUI.SetExtraInputAddUI(ExtraInputAddUI.ExtraInputType.TRANSACTION_WRITE);
        
        requestUI.SetExecuteButtonAction( () => {
            
            List<TransactionValue> transactionValues = new List<TransactionValue>();
            
            for (int i = 0; i < requestUI.GetValueInputFieldList().Count; i++) {
                
                switch (requestUI.GetValueInputFieldList()[i].dataType) {
                    case DataType.TRANSACTION_INSERT: 
                        string tableName = InputParseByString(i, 0);
                        string key = InputParseByString(i, 1);
                        string value = InputParseByString(i, 2);

                        Param insertParam = new Param();
                        insertParam.Add(key,value);
                        transactionValues.Add(TransactionValue.SetInsert(tableName, insertParam));
                        
                        break;
                    case DataType.TRANSACTION_UPDATE:
                        string tableName2 = InputParseByString(i, 0);
                        string key2 = InputParseByString(i, 1);
                        string value2 = InputParseByString(i, 2);
                        string userInDate = InputParseByString(i, 3);

                        Param updateParam = new Param();
                        updateParam.Add(key2,value2);

                        Where where = new Where();

                        if (string.IsNullOrEmpty(userInDate) == false) {
                            where.Equal("owner_inDate", userInDate);
                        }
                        
                        transactionValues.Add(TransactionValue.SetUpdate(tableName2, where, updateParam));
                        break;
                    case DataType.TRANSACTION_DELETE:
                        string tableName3 = InputParseByString(i, 0);
                        string rowInDate3 = InputParseByString(i, 1);
                        string userInDate3 = InputParseByString(i, 2);
                        
                        transactionValues.Add(TransactionValue.SetDeleteV2(tableName3, rowInDate3,userInDate3));

                        break;
                    case DataType.TRANSACTION_READ_QUERY:
                    case DataType.TRANSACTION_READ_INDATE:
                        throw new Exception($"{i + 1}번째 인자값 GET은 트랜잭션 쓰기에서 지원하지 않습니다.");
                    default:
                        throw new Exception($"{i + 1}번째 인자값은 지원하지 않습니다.\n{requestUI.GetValueInputFieldList()[i].dataType}");
                }
            }

            
            var bro = Backend.GameData.TransactionWriteV2(transactionValues);
            ShowResultData(bro);
        }); 
    }
    
        private void TransactionRead() {
            
            requestUI.SetExtraInputAddUI(ExtraInputAddUI.ExtraInputType.TRANSACTION_READ);

            requestUI.SetExecuteButtonAction( () => {
            
            List<TransactionValue> transactionValues = new List<TransactionValue>();
            
            for (int i = 0; i < requestUI.GetValueInputFieldList().Count; i++) {
                
                switch (requestUI.GetValueInputFieldList()[i].dataType) {
                    case DataType.TRANSACTION_READ_QUERY:
                        string tableName = InputParseByString(i, 0);
                        string queryKey = InputParseByString(i, 1);
                        string queryValue = InputParseByString(i, 2);

                        Where where = new Where();

                        if (!string.IsNullOrEmpty(queryKey) && !string.IsNullOrEmpty(queryValue)) {
                            where.Equal(queryKey, queryValue);
                        }
                        
                        transactionValues.Add(TransactionValue.SetGet(tableName, where));
                        break;
                    case DataType.TRANSACTION_READ_INDATE:
                        string tableName2 = InputParseByString(i, 0);
                        string rowInDate = InputParseByString(i, 1);
                        string userInDate = InputParseByString(i, 2);


                        transactionValues.Add(TransactionValue.SetGetV2(tableName2, rowInDate, userInDate));
                        break;
                    default:
                        throw new Exception($"{i + 1}번째 인자값은 지원하지 않습니다.\n{requestUI.GetValueInputFieldList()[i].dataType}");
                }
            }
            
            var bro = Backend.GameData.TransactionReadV2(transactionValues);
            ShowResultData(bro);
        }); 
    }
}