<?php
/**
 * @copyright Copyright (c) 2022 勾股工作室
 * @license https://opensource.org/licenses/GPL-3.0
 * @link https://www.gougucms.com
 */

declare (strict_types = 1);

namespace app\api\controller;

use app\api\ApiController;
use app\api\middleware\Auth;
use app\project\model\Project as ProjectList;
use app\project\validate\ProjectCheck;
use think\exception\ValidateException;
use think\facade\Db;

class ProjectIndex extends ApiController
{	

	protected $middleware = [
    	Auth::class => ['except' => []]
    ];

    public function index()
    {
		$this->checkAuth();
		$param = get_params();
		$where = array();
		if (!empty($param['director_uid'])) {
			$where[] = ['director_uid', 'in', $param['director_uid']];
		}
		if (!empty($param['status'])) {
			$where[] = ['status', 'in', $param['status']];
		}
		if (!empty($param['keyword'])) {
			$where[] = ['name|content', 'like', '%' . $param['keyword'] . '%'];
		}			
		$where[] = ['delete_time', '=', 0];
		$uid  = JWT_UID;
		$auth = isAuth($uid,'project_admin');
		if($auth == 0){
			$project_ids = Db::name('ProjectUser')->where(['uid' => $uid, 'delete_time' => 0])->column('project_id');
			$where[] = ['id', 'in', $project_ids];
		}	
		$rows = empty($param['limit']) ? get_config('app.page_size') : $param['limit'];
		$list = ProjectList::withoutField('content,md_content')
			->where($where)
			->order('id desc')
			->paginate($rows, false, ['query' => $param])
			->each(function ($item, $key) {
				$item->director_name = Db::name('Admin')->where(['id' => $item->director_uid])->value('name');
				$item->plan_time = date('Y-m-d', $item->start_time) . ' 至 ' . date('Y-m-d', $item->end_time);
				$item->status_name = ProjectList::$Status[(int) $item->status];
				$item->start_time = empty($item->start_time) ? '-' : date('Y-m-d H:i:s', $item->start_time);
				$item->end_time = empty($item->end_time) ? '-' : date('Y-m-d H:i:s', $item->end_time);
				$task_map = [];
				$task_map[] = ['project_id', '=', $item->id];
				$task_map[] = ['delete_time', '=', 0];
				//任务总数
				$item->tasks_total = Db::name('ProjectTask')->where($task_map)->count();
				//已完成任务
				$task_map[] = ['flow_status', '>', 2]; //已完成
				$item->tasks_finish = Db::name('ProjectTask')->where($task_map)->count();
				//未完成任务
				$item->tasks_unfinish = $item->tasks_total - $item->tasks_finish;
				if ($item->tasks_total > 0) {
					$item->tasks_pensent = round($item->tasks_finish / $item->tasks_total * 100, 2) . "％";
				} else {
					$item->tasks_pensent = "100％";
					if($item->status<2){
						$item->tasks_pensent = "0%";
					}
				}
				
				$step = Db::name('Step')->where(['action_id' => $item->id,'sort'=>$item->step_sort,'type'=>2,'delete_time'=>0])->find();
				if(!empty($step)){
					$item->step_user = Db::name('Admin')->where(['id'=>$step['flow_uid']])->value('name');
					$item->step = $step['flow_name'] . '-' . $item->step_user;
				}
				else{						
					$item->step = '-';
				}
			});
		$this->apiSuccess('获取成功', $list);
    }

    //添加
    public function add()
    {
		$this->checkAuth();
		$this->uid = JWT_UID;
        $param = get_params();
		try {
			validate(ProjectCheck::class)->scene('add')->check($param);
		} catch (ValidateException $e) {
			$this->apiError($e->getError());
		}
		if (isset($param['start_time'])) {
			$param['start_time'] = strtotime(urldecode($param['start_time']));
		}
		if (isset($param['end_time'])) {
			$param['end_time'] = strtotime(urldecode($param['end_time']));
		}
		
		$param['status'] = 2;
		$param['step_sort'] = 0;
		$flowNameData = isset($param['flow_name']) ? $param['flow_name'] : [];
		$flowUidsData = isset($param['charge_ids']) ? $param['charge_ids'] : [];
		$flowIdsData = isset($param['membe_ids']) ? $param['membe_ids'] : [];
		$flowDateData = isset($param['cycle_date']) ? $param['cycle_date'] : [];
		$flow = [];
		$time_1 = $param['start_time'];
		$time_2 = $param['end_time'];
		foreach ($flowNameData as $key => $value) {
			if (!$value) {
				continue;
			}				
			$flowDate = explode('到',$flowDateData[$key]);
			$start_time = strtotime(urldecode(trim($flowDate[0])));
			$end_time = strtotime(urldecode(trim($flowDate[1])));
			if($start_time<$time_1){
				if($key == 0){
					$this->apiError('第'.($key+1).'阶段的开始时间不能小于计划开始时间');
				}
				else{
					$this->apiError('第'.($key+1).'阶段的开始时间不能小于第'.($key).'阶段的结束时间');
				}
				break;
			}
			if($end_time>$time_2){
				$this->apiError('第'.($key+1).'阶段的结束时间不能大于计划结束时间');
				break;
			}
			else{
				$time_1 = $end_time;
			}
			$item = [];
			$item['flow_name'] = $value;
			$item['type'] = 2;
			$item['flow_uid'] = $flowUidsData[$key];
			$item['flow_ids'] = $flowIdsData[$key];
			$item['sort'] = $key;
			$item['start_time'] = $start_time;
			$item['end_time'] = $end_time;
			$item['create_time'] = time();
			$flow[]=$item;	
		}
		
		$param['create_time'] = time();
		$param['admin_id'] = $this->uid;
		$sid = ProjectList::strict(false)->field(true)->insertGetId($param);
		if ($sid) {
			$project_users = $this->uid;
			if (!empty($param['director_uid'])){
				$project_users.=",".$param['director_uid'];
			}
			if (!empty($param['team_admin_ids'])){
				$project_users.=",".$param['team_admin_ids'];
			}
			$project_array = explode(",",(string)$project_users);
			$project_array = array_unique($project_array);
			$project_user_array=[];
			foreach ($project_array as $k => $v) {
				if (is_numeric($v)) {
					$project_user_array[]=array(
						'uid'=>$v,
						'admin_id'=>$this->uid,
						'project_id'=>$sid,
						'create_time'=>time(),
					);
				}
			}
			Db::name('ProjectUser')->strict(false)->field(true)->insertAll($project_user_array);
			
			//增加阶段
			foreach ($flow as $key => &$value) {
				$value['action_id'] = $sid;
			}
			Db::name('Step')->strict(false)->field(true)->insertAll($flow);		
	
			add_log('add', $sid, $param);
			$log_data = array(
				'module' => 'project',
				'project_id' => $sid,
				'new_content' => $param['name'],
				'field' => 'new',
				'action' => 'add',
				'admin_id' => $this->uid,
				'old_content' => '',
				'create_time' => time(),
			);
			Db::name('ProjectLog')->strict(false)->field(true)->insert($log_data);
		}
		$this->apiSuccess('操作成功');
    }

    //编辑
    public function edit()
    {
		$this->checkAuth();
		$this->uid = JWT_UID;
        $param = get_params();
        $id = isset($param['id']) ? $param['id'] : 0;
		$detail = (new ProjectList())->detail($id);
		try {
			validate(ProjectCheck::class)->scene('edit')->check($param);
		} catch (ValidateException $e) {
			$this->apiError($e->getError());
		}
		if ($this->uid == $detail['admin_id'] || $this->uid == $detail['director_uid']) {
			if (isset($param['start_time'])) {
				$param['start_time'] = strtotime(urldecode($param['start_time']));
				if ($param['start_time'] >= $detail['end_time']) {
					return to_assign(1, '开始时间不能大于计划结束时间');
				}
			}
			if (isset($param['end_time'])) {
				$param['end_time'] = strtotime(urldecode($param['end_time']));
				if ($param['end_time'] <= $detail['start_time']) {
					return to_assign(1, '计划结束时间不能小于开始时间');
				}
			}
			$param['update_time'] = time();
			$res = ProjectList::where('id', $param['id'])->strict(false)->field(true)->update($param);
			if ($res) {
				if(isset($param['director_uid'])){
					$project_user=array(
						'uid'=>$param['director_uid'],
						'admin_id'=>$this->uid,
						'project_id'=>$param['id'],
						'create_time'=>time(),
						'delete_time'=>0,
					);
					$has = Db::name('ProjectUser')->where(array('uid'=>$param['director_uid'],'project_id'=>$param['id']))->find();
					if(empty($has)){
						Db::name('ProjectUser')->strict(false)->field(true)->insert($project_user);
					}
					else{
						Db::name('ProjectUser')->where(array('id'=>$has['id']))->strict(false)->field(true)->update($project_user);						
					}
				}
				add_log('edit', $param['id'], $param);
				add_project_log($this->uid,'project',$param, $detail);
			}
			$this->apiSuccess('操作成功');
		} else {
			$this->apiError('只有创建人或者负责人才有权限修改项目', [], 2);
		}
		
    }

    //查看
    public function view()
    {
		$this->checkAuth();
		$this->uid = JWT_UID;
        $param = get_params();
        $id = isset($param['id']) ? $param['id'] : 0;
        $detail = (new ProjectList())->detail($id);
        if (empty($detail)) {
			$this->apiError("项目不存在");
        } else {
            $tids = Db::name('ProjectTask')->where([['project_id', '=', $detail['id']], ['delete_time', '=', 0]])->column('id');
            $detail['schedules'] = Db::name('Schedule')->where([['tid', 'in', $tids], ['delete_time', '=', 0]])->count();
            $detail['hours'] = Db::name('Schedule')->where([['tid', 'in', $tids], ['delete_time', '=', 0]])->sum('labor_time');
            $detail['plan_hours'] = Db::name('ProjectTask')->where([['project_id', '=', $detail['id']], ['delete_time', '=', 0]])->sum('plan_hours');
			
			$detail['tasks'] = Db::name('ProjectTask')->where([['project_id', '=', $detail['id']],['delete_time', '=', 0]])->count();
            $detail['tasks_finish'] = Db::name('ProjectTask')->where([['project_id', '=', $detail['id']],['flow_status', '>', 2], ['delete_time', '=', 0]])->count();
            $detail['tasks_unfinish'] = $detail['tasks'] - $detail['tasks_finish'];
			$detail['start_time'] = date('Y-m-d H:i:s', $detail['start_time']);
			$detail['end_time'] = date('Y-m-d H:i:s', $detail['end_time']);
			$detail['create_time'] = date('Y-m-d H:i:s', $detail['create_time']);
		
			//相关附件
			$file_array = Db::name('ProjectFile')
                ->field('mf.id,mf.topic_id,mf.admin_id,f.name,f.filesize,f.filepath,f.fileext,f.create_time,f.admin_id,a.name as admin_name')
                ->alias('mf')
                ->join('File f', 'mf.file_id = f.id', 'LEFT')
                ->join('Admin a', 'mf.admin_id = a.id', 'LEFT')
                ->order('mf.create_time desc')
                ->where(array('mf.topic_id' => $id, 'mf.module' => 'project'))
                ->select()->toArray();
				
			//相关链接
			$link_array = Db::name('ProjectLink')
                ->field('i.id,i.topic_id,i.admin_id,i.desc,i.url,a.name as admin_name')
                ->alias('i')
                ->join('Admin a', 'i.admin_id = a.id', 'LEFT')
                ->order('i.create_time desc')
                ->where(array('i.topic_id' => $id, 'i.module' => 'project', 'delete_time' => 0))
                ->select()->toArray();
		
			//项目阶段			
			$step_array = Db::name('Step')
				->field('s.*,a.name as check_name')
				->alias('s')
				->join('Admin a', 'a.id = s.flow_uid', 'LEFT')
				->order('s.sort asc')
				->where(array('s.action_id' => $id, 's.type' => 2, 's.delete_time' => 0))
				->select()->toArray();
			foreach ($step_array as $k => $v) {		
				$step_array[$k]['start_time'] = date('Y-m-d H:i:s', $v['start_time']);
				$step_array[$k]['end_time'] = date('Y-m-d H:i:s', $v['end_time']);
				$step_array[$k]['create_time'] = date('Y-m-d H:i:s', $v['create_time']);
			}

			//阶段操作记录			
			$step_record = Db::name('StepRecord')
				->field('s.*,a.name as check_name,p.flow_name')
				->alias('s')
				->join('Admin a', 'a.id = s.check_uid', 'LEFT')
				->join('Step p', 'p.id = s.step_id', 'LEFT')
				->order('s.check_time asc')
				->where(array('s.action_id' => $id, 's.type' => 2))
				->select()->toArray();		
			foreach ($step_record as $kk => &$vv) {		
				$vv['check_time_str'] = date('Y-m-d H:i:s', $vv['check_time']);
				$vv['check_time'] = date('Y-m-d H:i:s', $vv['check_time']);
				$vv['status_str'] = '提交';
				if($vv['status'] == 1){
					$vv['status_str'] = '确认完成';
				}
				else if($vv['status'] == 2){
					$vv['status_str'] = '回退';
				}
				if($vv['status'] == 3){
					$vv['status_str'] = '撤销';
				}
				if($vv['content'] == ''){
					$vv['content'] = '无';
				}
			}
			
			//当前项目阶段
			$step = Db::name('Step')->where(array('action_id' => $id, 'type' => 2, 'sort' => $detail['step_sort'],'delete_time'=>0))->find();
			if(!empty($step)){
				$step['check_name'] = Db::name('Admin')->where(['id' => $step['flow_uid']])->value('name');
				$flow_names = Db::name('Admin')->where([['id','in',$step['flow_ids']]])->column('name');
				$step['flow_names'] = implode(',',$flow_names);
				$step['start_time'] = date('Y-m-d H:i:s', $step['start_time']);
				$step['end_time'] = date('Y-m-d H:i:s', $step['end_time']);
				$step['create_time'] = date('Y-m-d H:i:s', $step['create_time']);
				if ($this->uid == $step['flow_uid']){		
					$is_check_admin = 1;
				}
			}
            $this->apiSuccess('获取成功', compact('file_array', 'link_array', 'step', 'step_array', 'step_record', 'detail'));
        }
    }

    //删除
    public function delete()
    {
		$this->checkAuth();
		$this->uid = JWT_UID;
		$id = get_params("id");
		$project = Db::name('project')->where([
            'id' => $id
        ])->findOrEmpty();
        if (empty($project)) {
			$this->apiError('项目不存在');
        }
		$count_task = Db::name('ProjectTask')->where([['project_id', '=', $id], ['delete_time', '=', 0]])->count();
		if ($count_task > 0) {
			$this->apiError('该项目下有关联的任务，无法删除');
		}
		$detail = Db::name('Project')->where('id', $id)->find();
		if ($detail['admin_id'] != $this->uid) {
			$this->apiError('你不是该项目的创建人，无权限删除', [], 2);
		}
		if (Db::name('Project')->where('id', $id)->update(['delete_time' => time()]) !== false) {
			$log_data = array(
				'module' => 'project',
				'field' => 'delete',
				'action' => 'delete',
				'project_id' => $detail['id'],
				'admin_id' => $this->uid,
				'old_content' => '',
				'new_content' => $detail['name'],
				'create_time' => time(),
			);
			Db::name('ProjectLog')->strict(false)->field(true)->insert($log_data);
			$this->apiSuccess('删除成功');
		} else {
			$this->apiError('删除失败');
		}
    }

	//添加附件
	public function add_file()
	{
		$param = get_params();
		$this->uid = JWT_UID;
		if (empty($param['topic_id'])) {
            $this->apiError("项目id不能为空");
        }
        if (empty($param['file_id'])) {
            $this->apiError("文件id不能为空");
        }
        if (empty($param['file_name'])) {
            $this->apiError("文件名称不能为空");
        }
		if (empty($param['module'])) {
			// project
            $this->apiError("模块不能为空");
        }
        $param['create_time'] = time();
        $param['admin_id'] = $this->uid;
        $fid = Db::name('ProjectFile')->strict(false)->field(true)->insertGetId($param);
        if ($fid) {
            $log_data = array(
                'module' => $param['module'],
                'field' => 'file',
                'action' => 'upload',
                $param['module'] . '_id' => $param['topic_id'],
                'admin_id' => $this->uid,
                'old_content' => '',
                'new_content' => $param['file_name'],
                'create_time' => time(),
            );
            Db::name('ProjectLog')->strict(false)->field(true)->insert($log_data);
			$this->apiSuccess('添加附件成功');
        }
		$this->apiError('添加附件失败');
	}

	//删除附件
    public function delete_file()
    {
		$id = get_params("id");
		if (empty($id)) {
            $this->apiError("项目文件id不能为空");
        }
		$detail = Db::name('ProjectFile')->where('id', $id)->find();
		if ($detail && Db::name('ProjectFile')->where('id', $id)->delete() !== false) {
			$file_name = Db::name('File')->where('id', $detail['file_id'])->value('name');
			$log_data = array(
				'module' => $detail['module'],
				'field' => 'file',
				'action' => 'delete',
				$detail['module'] . '_id' => $detail['topic_id'],
				'admin_id' => $this->uid,
				'new_content' => $file_name,
				'create_time' => time(),
			);
			Db::name('ProjectLog')->strict(false)->field(true)->insert($log_data);
			$this->apiSuccess('删除成功');
		} else {
			$this->apiError('删除失败');
		}
    }
	
	//链接添加修改
	public function add_link()
	{
		$param = get_params();
		$this->uid = JWT_UID;
		if (empty($param['topic_id'])) {
            $this->apiError("项目id不能为空");
        }
        if (empty($param['url'])) {
            $this->apiError("url不能为空");
        }
        if (empty($param['desc'])) {
            $this->apiError("说明不能为空");
        }
		if (empty($param['module'])) {
			// project
            $this->apiError("模块不能为空");
        }
		$validate = \think\facade\Validate::rule([
			'url' => 'url',
		]);
		if (!$validate->check($param)) {
			$this->apiError($validate->getError());
		}
		if (!empty($param['id']) && $param['id'] > 0) {
			$param['update_time'] = time();
			$res = Db::name('ProjectLink')->where('id', $param['id'])->strict(false)->field(true)->update($param);
			if ($res) {
				$log_data = array(
					'module' => $param['module'],
					'field' => 'link',
					'action' => 'edit',
					$param['module'] . '_id' => $param['topic_id'],
					'admin_id' => $this->uid,
					'old_content' => $param['url'],
					'new_content' => $param['desc'],
					'create_time' => time(),
				);
				Db::name('ProjectLog')->strict(false)->field(true)->insert($log_data);
				$this->apiSuccess('编辑成功');
			}
		} else {
			$param['create_time'] = time();
			$param['admin_id'] = $this->uid;
			$lid = Db::name('ProjectLink')->strict(false)->field(true)->insertGetId($param);
			if ($lid) {
				$log_data = array(
					'module' => $param['module'],
					'field' => 'link',
					'action' => 'add',
					$param['module'] . '_id' => $param['topic_id'],
					'admin_id' => $this->uid,
					'new_content' => $param['desc'],
					'create_time' => time(),
				);
				Db::name('ProjectLog')->strict(false)->field(true)->insert($log_data);
				$this->apiSuccess('添加成功');
			}
		}
	}

	//删除
	public function delete_link()
	{
		$id = get_params("id");
		if (empty($id)) {
            $this->apiError("项目链接id不能为空");
        }
		$id = get_params("id");
		$detail = Db::name('ProjectLink')->where('id', $id)->find();
		if ($detail && Db::name('ProjectLink')->where('id', $id)->update(['delete_time' => time()]) !== false) {
			$log_data = array(
				'module' => $detail['module'],
				'field' => 'link',
				'action' => 'delete',
				$detail['module'] . '_id' => $detail['topic_id'],
				'admin_id' => $this->uid,
				'new_content' => $detail['desc'],
				'create_time' => time(),
			);
			Db::name('ProjectLog')->strict(false)->field(true)->insert($log_data);
			$this->apiSuccess('删除成功');
		} else {
			$this->apiError('删除失败');
		}
		
	}
}
