<?php

namespace app\controller;

use think\facade\Request;
use think\helper\Arr;


/**
 * 学者分析
 */
class EsAuthor extends CommonEsController
{

    protected $pageSize = 20;


    public function test()
    {
        return $this->_json_succ(
            [
                'name' => 'knowledge',
                'value' => 'sk'
            ]
        );
    }


    /**
     * 首页
     */
    public function index()
    {
        $field = Request::param('field') ?? 'author_org_list';
        $page = Request::param('page') ?? 1;
        $limit = ($page - 1) * $this->pageSize;

        $params = [
            'index' => 'document_zh',
//            'index' => 'document_zh,document_en',
            'body' => [
                'from' => $limit,
                'size' => $this->pagesize,
                'query' => [
                    'match_all' => (object)[],      // 查询全部
                ],
                "_source" => $field,                  // 获取制定字段
                //"sort"    => $this->setOrderOther(),
            ]
        ];
	//print_r($params);die;
        $result = $this->esCommonGetData($params);
	$data = $result['data'];
        $column = array_column($data, 'author_org_list');
        $author = array_merge(
            //$column[0] ?? [], $column[1] ?? [],$column[2] ?? [],$column[3] ??[],$column[4] ?? [] , $column[5] ?? []
	    $column[0] ?? [], $column[1] ?? [], $column[2] ?? []
        );
	if(count($author) < 12){
	    $author = array_merge($author,$column[3] ?? [],$column[4] ?? [],$column[5] ?? []);
	}

        /**
         * 查询作者的成果数和被引频次
         */
        $newAuthorOrg = [];
        foreach ($author as $key => $value) {
            $authorOrg = explode('#', $value);
            $newAuthorOrg[$key]['author'] = $authorOrg[0];
            $newAuthorOrg[$key]['org'] = $authorOrg[1];
            $bucket = $this->getAuthorCount($value);
            $newAuthorOrg[$key]['achievement_num'] = $bucket[0]['doc_count'] ?? '';
            $newAuthorOrg[$key]['citation_frequency'] = $bucket[0]['citedCnt']['value'] ?? '';
        }
	
        return $this->_json_succ(
            $newAuthorOrg
        );
    }


    /**
     * 获取作者的机构
     */
    protected function getAuthorOrg($author, $authorList)
    {
//        foreach ($authorList as $value){
//            $arr = explode('#',$value);
//            if (in_array($author,$arr)){
//                return  Arr::get($arr,1);
//            }
//        }
        $params = [
            'index' => 'document_zh',
            'from' => 0,
            'size' => 1,
            'body' => [
                'query' => [
                    'match_phrase' => [
                        'author_org_list' => $author
                    ]
                ]
            ]
        ];

        $client = $this->getEsClient();
        $result = $client->search($params);

        if (!isset($result['hits']['hits'][0])) {
            return '';
        }

        $org = $result['hits']['hits'][0]['_source']['author_org'];
        foreach ($org as $value) {
            if (($author == $value['author']) || (stripos($value['author'], $author) !== false)) {
                return $value['org'];
            }
        }
        return '';
    }


    /**
     * 作者的成果数 ｜ 被引频次
     */
    protected function getAuthorCount($authors)
    {

        $query['bool']['should'][] = [
            'term' => [
                'author_org_list.keyword' => [
                    'value' => $authors
                ]
            ]
        ];
        $size = 1;
        $params = [
            'index' => 'document_zh',
            'body' => [
                'size' => 1,
                'query' => $query,
                'aggs' => [
                    'author' => [
                        'terms' => [
                            'field' => 'author_list.keyword',
                            'size' => $size,
                            'order' => [
                                '_count' => 'desc'
                            ]
                        ],
                        'aggs' => [
                            'citedCnt' => [
                                'sum' => [
                                    'field' => 'citation_relate_count'
                                ]
                            ]
                        ]
                    ]
                ]
            ]
        ];

        $client = $this->getEsClient();
        $result = $client->search(
            $params
        );
        return $result['aggregations']['author']['buckets'];
    }


    /**
     * 作者对应的所有机构（下拉）
     */
    public function getSelectOrgs()
    {
        $author = Request::param('author') ?? '';
        if (!$author) {
            return $this->_json_error('请求参数错误！');
        }

        $page = Request::param('page') ?? 1;
        $size = 100;
        $limit = ($page - 1) * $size;

        $params = [
            'index' => 'document_zh',
            'from' => $limit,
            'size' => $size,
            'body' => [
                'query' => [
                    'match_phrase' => [
                        'author_org_list' => $author
                    ]
                ]
            ]
        ];

        $client = $this->getEsClient();
        $result = $client->search($params);
        $total = $result['hits']['total'];
        if (0 == $total) {
            return $this->_json_error('未查到相关信息！');
        }

        $hits = $result['hits']['hits'];
        $source = array_column($hits, '_source');
        $authorOrgList = array_column($source, 'author_org_list');

        $authorSelectList = [];
        foreach ($authorOrgList as $value) {
            if (!is_array($value)) {
                $varr = explode('#', $value);
                if ($author == $varr[0]) {
                    $authorSelectList[] = $value;
                }
            } else {
                foreach ($value as $v) {
                    $varr = explode('#', $v);
                    if ($author == $varr[0]) {
                        $authorSelectList[] = $v;
                    }
                }
            }
        }

        if (empty($authorSelectList)) {
            return $this->_json_succ(
                []
            );
        }

        foreach ($authorSelectList as $kk => $vv) {
            $arr = explode('#', $vv);
            $newArray[$kk]['author'] = $arr[0];
            $newArray[$kk]['org'] = $arr[1];
        }

        $orgs = array_values(array_unique(array_column($newArray, 'org')));
        return $this->_json_succ(
            [
                'orgs' => $orgs
            ]
        );
    }


    /**
     * 搜索
     */
    public function search()
    {
        $author = Request::param('author') ?? '';
        $org = Request::param('org') ?? '';
        $tag = Request::param('tag') ?? '';
        $page = Request::param('page') ?? 1;
        $pageSize = Request::param('pageSize') ?? 12;

        if (!$author && !$org) {
            return $this->_json_error('请求参数有误！');
        }

        if ($author && $org) {
            $value = $author . '#' . $org;
            $selectTag = 'author-org';
            $size = 1;
        }

        if ($author && !$org) {
            $value = $author;
            $selectTag = 'author';
            $size = 1000;
        }

        if (!$author && $org) {
            $value = $org;
            $selectTag = 'org';
            $size = 1000;
        }

        $field = 'author_org_list';
        $params = [
            'index' => 'document_zh',
            'size' => 1,
            'body' => [
                'query' => [
                    'match_phrase' => [
                        $field => $value
                    ]
                ],
                'aggs' => [
                    'author_group' => [
                        'terms' => [
                            'field' => 'author_org_list.keyword',
                            'size' => $size,
                        ]
                    ]
                ]
            ]
        ];

        $client = $this->getEsClient();
        $result = $client->search(
            $params
        );

        $total = $result['hits']['total'];
        if (0 == $total) {
            return $this->_json_error('未查到相关信息！');
        }

        $newArray = [];

        $authorOrgGroup = $result['aggregations']['author_group']['buckets'];
        foreach ($authorOrgGroup as $kk => $vv) {
            $arr = explode('#', $vv['key']);
            $newArray[$kk]['author'] = $arr[0];
            $newArray[$kk]['org'] = $arr[1];
        }
        if ($selectTag == 'org'){
            $uniqueArray = $this->uniqueArr($newArray, 'author', $org);
        }else{
            $uniqueArray = $this->uniqueArr($newArray, 'org', $author);
        }

        $newArray = [];
        foreach ($uniqueArray as $key => $value) {
            //实现分页操作
            if ((($page - 1) * $pageSize) > $key) {
                continue;
            }
            if (($page * $pageSize - 1) < $key) {
                continue;
            }
            $newArray[$key]['author'] = $value['author'];
            $newArray[$key]['org'] = $value['org'];
            $bucket = $this->getAuthorCount($value['author'] . '#' . $value['org']);
            $newArray[$key]['achievement_num'] = $bucket[0]['doc_count'] ?? 0;
            $newArray[$key]['citation_frequency'] = $bucket[0]['citedCnt']['value'] ?? 0;
        }

        return $this->_json_succ(
            [
                'total' => count($uniqueArray),
                'total_page' => ceil(count($uniqueArray) / $pageSize),
                'data' => $newArray,
            ]
        );
    }


    /**
     * 二维数组某个键值唯一
     */
    protected function uniqueArr($arr, $key, $value)
    {

        $newArray = [];
        foreach ($arr as $k => $v) {
            if (empty($newArray)) {
                $newArray[] = $arr[0][$key];
            } else {
                if (in_array($v[$key], $newArray)) {
                    unset($arr[$k]);
                } else {
                    $newArray[] = $v[$key];
                }
            }
        }

        if ('org' === $key) {
            $authorOrgList = [];
            foreach ($newArray as $kk => $vv) {
                $authorOrgList[$kk]['author'] = $value;
                $authorOrgList[$kk]['org'] = $vv;
            }
            return $authorOrgList;
        }

        if ('author' === $key) {
            $orgAuthorList = [];
            foreach ($newArray as $kkk => $vvv) {
                $orgAuthorList[$kkk]['author'] = $vvv;
                $orgAuthorList[$kkk]['org'] = $value;
            }
            return array_slice($orgAuthorList, 0, 20);
        }
        return [];
    }


    /**
     * 获取学者机构
     */
    public function getOrganization()
    {
        $author = Request::param('author') ?? '';
        $title = strip_tags(Request::param('title')) ?? '';

        $params = [
            'index' => 'document_zh',
            'body' => [
                'size' => 1,
                'query' => [
                    'bool' => [
                        'must' => [
                            [
                                'term' => [
                                    'title.keyword' => $title,
                                ]
                            ],
                            [
                                'term' => [
                                    'author_list.keyword' => $author
                                ]
                            ]
                        ],
                    ]
                ],
                //"_source" => $field,                  // 获取制定字段
                //"sort"    => $this->setOrderOther(),
            ]
        ];

        $client = $this->getEsClient();
        $result = $client->search($params);
        $total = $result['hits']['total'];
        $data = $result['hits']['hits'];

        $org['org'] = '';
        if (0 == $total) {
            return $this->_json_succ(
                $org
            );
        }

        $source = array_column($data, '_source');
        $authorOrgList = array_column($source, 'author_org_list');

        $str = [];
        foreach ($authorOrgList as $key => $value) {
            $valueCount = count($authorOrgList[$key]);
            for ($i = 0; $i < $valueCount; $i++) {
                $orgAuthor = $value[$i];
                if (stripos($orgAuthor, $author) !== false) {
                    $str = $orgAuthor;
                }
            }
        }

        if (empty($str)) {
            return $this->_json_succ(
                $org
            );
        }

        $authorOrgArr = explode('#', $str);
        $org = $authorOrgArr[1] ?? '';

        return $this->_json_succ(
            [
                'org' => $org
            ]
        );
    }


    /**
     * 学者详情
     */
    public function getAuthorDetailByName()
    {
        $author = Request::param('author') ?? '';
        $org = Request::param('org') ?? '';
        if (!$author || !$org) {
            return $this->_json_error('请求参数有误！');
        }

        $authorDetail = [
            'author' => $author,
            'org' => $org,
            'achievement_num' => $this->authorDetail($author, $org, 'achievement_num'),
            'citation_frequency' => $this->authorDetail($author, $org, 'citation_frequency'),
            'cooperation_partner_num' => $this->authorDetail($author, $org, 'cooperation_partner_num'),
            'cooperation_organization_num' => $this->authorDetail($author, $org, 'cooperation_organization_num'),
            'co_author_list' => $this->authorDetail($author, $org, 'co_author_list'),
            'post_trend' => $this->authorDetail($author, $org, 'post_trend'),
            'cited_trend' => $this->authorDetail($author, $org, 'cited_trend'),
            'research_topic' => $this->authorDetail($author, $org, 'research_topic'),
            'co_organization_list' => $this->authorDetail($author, $org, 'co_organization_list'),
            'domain' => $this->authorDetail($author, $org, 'domain')
        ];

        return $this->_json_succ(
            $authorDetail
        );
    }


    /**
     * 学者详情统计
     */
    protected function authorDetail($author, $org, $tag)
    {
        //$index = $this->currentLanguage();
        $index = 'document_zh';
        $params = [
            'index' => $index,
            'body' => [
                'query' => [
                    'bool' => [
                        'should' => [
                            'term' => [
                                'author_org_list.keyword' => [
                                    'value' => $author . '#' . $org
                                ]
                            ]
                        ],
                        'minimum_should_match' => 1
                    ]
                ],
                'aggs' => [
                    'corAuthorCnt' => [
                        'cardinality' => [
                            'field' => 'author_list.keyword',
                            'precision_threshold' => 1000
                        ]
                    ],
                    'corOrgCnt' => [
                        'cardinality' => [
                            'field' => 'organization_parsed.keyword'
                        ]
                    ],
                    'citedCnt' => [
                        'sum' => [
                            'field' => 'citation_relate_count'
                        ]
                    ],
                    'corAuthors' => [
                        'terms' => [
                            'field' => 'author_org_list.keyword',
                            'order' => [
                                '_count' => 'desc',
                            ],
                            'size' => 50
                        ]
                    ],
                    'corOrgs' => [
                        'terms' => [
                            'field' => 'organization_parsed.keyword',
                            'order' => [
                                '_count' => 'desc'
                            ],
                            'size' => 50
                        ]
                    ],
                    'docStat' => [
                        'terms' => [
                            'field' => 'year',
                            'order' => [
                                '_key' => 'asc',
                            ],
                            "size" => 50
                        ],
                        'aggs' => [
                            'yearCitedCnt' => [
                                'sum' => [
                                    'field' => 'citation_relate_count'
                                ]
                            ]
                        ]
                    ],
                    'keywordCnt' => [
                        'terms' => [
                            'field' => 'keyword_list.keyword',
                            'order' => [
                                '_count' => 'desc'
                            ],
                            'size' => 20
                        ]
                    ]
                ]
            ]
        ];

        $client = $this->getEsClient();
        $result = $client->search($params);

        $newCitedTrend = [];
        $citedTrend = $result['aggregations']['docStat']['buckets'];
        foreach ($citedTrend as $key => $value) {
            $newCitedTrend[$key]['key'] = $value['key'];
            $newCitedTrend[$key]['doc_count'] = $value['yearCitedCnt']['value'];
        }

        $corAuthors = $result['aggregations']['corAuthors']['buckets'];
        $nerCorAuthors = [];
        foreach ($corAuthors as $key => $value) {
            $authorOrg = explode('#', $value['key']);
            $nerCorAuthors[$key]['key'] = $authorOrg[0];
            $nerCorAuthors[$key]['org'] = $authorOrg[1];
        }

        $research_topic = $result['aggregations']['keywordCnt']['buckets'];
        $authorDetail = [
            'achievement_num' => $result['hits']['total'],
            'citation_frequency' => $result['aggregations']['citedCnt']['value'],
            'cooperation_partner_num' => $result['aggregations']['corAuthorCnt']['value'],
            'cooperation_organization_num' => $result['aggregations']['corOrgCnt']['value'],
            'co_author_list' => $nerCorAuthors,
            'post_trend' => $result['aggregations']['docStat']['buckets'],
            'cited_trend' => $newCitedTrend,
            'research_topic' => $research_topic,
            'co_organization_list' => $result['aggregations']['corOrgs']['buckets'],
            'domain' => array_column($research_topic, 'key')
        ];
        return $authorDetail[$tag];
    }
}
