<?php

  namespace App\Controllers;

  use CodeIgniter\RESTful\ResourceController;

  class Winner extends ResourceController
  {
    //당첨자 리스트
    public function winnerlist()
    {      
      $db = \Config\Database::connect();

      // POST JSON 파라미터 받기
      $request = $this->request->getJSON(true);
      if (!isset($request['compId'])) {
        return $this->respond([
          'status' => 'fail',
          'message' => 'filter(compId)가 누락되었습니다.'
        ], 400);
      }
      $status = isset($request['status']) ? $request['status'] : null;
      $compId = $request['compId'];
      // 쿼리 빌더
      $builder = $db->table('EVT_LIST');
      // compId가 '0-000000'이 아닐 때만 COMP_ID 조건 추가
      if ($compId !== '0-000000') {
        $builder->where('COMP_ID', $compId);
      }
      if ($status !== null) {
        // status가 넘어오면 해당 값만 검색
        $builder->where('status', $status);
      }

      $lists = $builder->get()->getResultArray();

      foreach ($lists as &$row) {
        if (isset($row['STARTDATE']) && !empty($row['STARTDATE'])) {
          $row['STARTDATE'] = date('Y-m-d', strtotime($row['STARTDATE']));
        }
        if (isset($row['ENDDATE']) && !empty($row['ENDDATE'])) {
          $row['ENDDATE'] = date('Y-m-d', strtotime($row['ENDDATE']));
        }
      }




      // 반환 데이터 가공 (필요시)
      $filtered = array_reverse($lists);

      return $this->respond($filtered, 200);

    }

    //이벤트 마감 체크
    public function winnerChk()
    {
      $db = \Config\Database::connect();

      $seq = null;
      $requestJson = $this->request->getJSON(true);
      if (is_array($requestJson) && isset($requestJson['seq'])) {
        $seq = $requestJson['seq'];
      }
      
      if (empty($seq)) {
        return $this->respond(['status' => 'fail', 'message' => '필수 파라미터 누락'], 400);
      }



      // EVT_ITEM에서 해당 seq 로 아이템과 WIN_QTY 조회
      $items = $db->table('EVT_ITEM')
        ->select('ITEM_SEQ, WIN_QTY')
        ->where('EVT_SEQ', $seq)
        ->get()->getResultArray();

      // 아이템별 최대 당첨자수 배열 구성
      $maxWinners = [];
      foreach ($items as $idx => $item) {
        $rank = $idx + 1; // 1등부터 시작
        $maxWinners[$rank] = (int)$item['WIN_QTY'];
      }

      // PARTICIPATION_LIST에서 seq로 당첨자 집계 (RANK별 COUNT)
      $counts = [];
      $results = $db->table('PARTICIPATION_LIST')
        ->select('RANK, COUNT(*) as cnt')
        ->where('EVT_SEQ', $seq)
        ->groupBy('RANK')
        ->get()->getResultArray();
      foreach ($results as $row) {
        $counts[(int)$row['RANK']] = (int)$row['cnt'];
      }

      // 모든 RANK의 당첨자수가 max와 같거나 크면 "마감"
      $isClosed = true;
      foreach ($maxWinners as $rank => $qty) {
        $curr = isset($counts[$rank]) ? $counts[$rank] : 0;
        if ($curr < $qty) {
          $isClosed = false;
          break;
        }
      }

      if ($isClosed) {
        return $this->respond(['status' => 'closed', 'message' => '마감되었습니다'], 200);
      } else {
        return $this->respond(['status' => 'open', 'message' => '아직 마감 아님'], 200);
      }

    }

    //당첨자 등록 및 랭크 반환
    public function winnerReg()
    {
      $db = \Config\Database::connect();

      // 파라미터 추출
      $seq = null;
      $name = null;
      $phone = null;

      $request = $this->request->getJSON(true);
      if (is_array($request) && isset($request['seq'])) {
          $seq = $request['seq'];
          $name = $request['name'];
          $phone = $request['phone'];
      } else {
          $seq = $this->request->getPost('seq');
          $name = $this->request->getPost('name');
          $phone = $this->request->getPost('phone');
      }

      // 등수별 설정 및 ITEM_NAME 매핑
      $rankConfigs = [];
      $itemNames = [];

      if (!empty($seq)) {
          $builder = $db->table('EVT_ITEM');
          $builder->select('WIN_RATE, WIN_QTY, ITEM_NAME');
          $builder->where('EVT_SEQ', $seq);
          $builder->orderBy('ITEM_SEQ', 'ASC');
          $rows = $builder->get()->getResultArray();

          foreach ($rows as $i => $row) {
              $rank = $i + 1; // 1등부터 시작
              $rankConfigs[$rank] = [
                  'percent' => (int)$row['WIN_RATE'],
                  'max' => (int)$row['WIN_QTY']
              ];
              $itemNames[$rank] = $row['ITEM_NAME'];
          }
      }

      // 등수별 참여자 집계
      $builder = $db->table('PARTICIPATION_LIST')
          ->select('RANK, COUNT(*) AS cnt')
          ->where('EVT_SEQ', $seq)
          ->groupBy('RANK');
      $result = $builder->get()->getResultArray();

      $winnerCounts = [];
      foreach ($result as $row) {
          $winnerCounts[(int)$row['RANK']] = (int)$row['cnt'];
      }

      // 가능한 등수 구하기
      $availableRanks = [];
      $totalPercent = 0;
      foreach ($rankConfigs as $rank => $cfg) {
          $cnt = isset($winnerCounts[$rank]) ? $winnerCounts[$rank] : 0;
          if ($cnt < $cfg['max']) {
              $availableRanks[] = [
                  'rank' => $rank,
                  'percent' => $cfg['percent']
              ];
              $totalPercent += $cfg['percent'];
          }
      }

      //      if (empty($availableRanks)) {
      //          return $this->respond(['status' => 'fail', 'message' => '모든 등수 당첨자가 마감되었습니다.'], 200);
      //      }

      if (empty($availableRanks)) {
          // 등수 마감 상태 => rank 0으로 처리
          $selectedRank = 0;
          $selectedItemName = "꽝";
          $rankIndex = 0;
      } else {
          // 기존 랜덤 등수 추출
          $rand = mt_rand() / mt_getrandmax() * $totalPercent;
          foreach ($availableRanks as $cfg) {
              if ($rand < $cfg['percent']) {
                  $selectedRank = $cfg['rank'];
                  break;
              }
              $rand -= $cfg['percent'];
          }
          if (!isset($selectedRank)) {
              $selectedRank = $availableRanks[count($availableRanks) - 1]['rank'];
          }
          $selectedItemName = isset($itemNames[$selectedRank]) ? $itemNames[$selectedRank] : null;

          // RANK_INDEX 구하기
          $builder = $db->table('PARTICIPATION_LIST');
          $builder->selectMax('RANK_INDEX');
          $builder->where('EVT_SEQ', $seq);
          $builder->where('RANK', $selectedRank);
          $rankIndexRow = $builder->get()->getRowArray();
          $rankIndex = isset($rankIndexRow['RANK_INDEX']) && $rankIndexRow['RANK_INDEX'] ? ((int)$rankIndexRow['RANK_INDEX']) + 1 : 1;
      }

      // DB 저장
      $insertData = [
          'EVT_SEQ'     => $seq,
          'RANK'        => $selectedRank,
          'ITEM_NAME'   => $selectedItemName,
          'NAME'        => $name,
          'PHONE'       => $phone,
          'RANK_INDEX'  => $rankIndex,
          'PRIVACY_AGREE' => 1,
          'THIRDPARTY_AGREE' => 1
      ];
      $db->table('PARTICIPATION_LIST')->insert($insertData);

      // 응답
      return $this->respond([
          'rank' => $selectedRank,
          'item_name' => $selectedItemName,
          'rank_index' => $rankIndex,
          'name' => $name,
          'phone' => $phone,
      ], 200);
    }

    //아이템 리스트
    public  function itemCount()
    {
      $db = \Config\Database::connect();
      // POST 파라미터 JSON 또는 폼에서 받기 (JSON 우선)
      $seq = null;
      $request = $this->request->getJSON(true);
      if (is_array($request) && isset($request['seq'])) {
        $seq = $request['seq'];
      } else {
        $seq = $this->request->getPost('seq'); // 폼 방식 대비
      }

      if (empty($seq)) {
        return $this->respond(['status' => 'fail', 'message' => 'seq 파라미터가 필요합니다.'], 400);
      }

      $builder = $db->table('EVT_ITEM');
      $builder->select('ITEM_NAME');
      $builder->where('EVT_SEQ', $seq);
      $query = $builder->get();
      $items = [];
      foreach ($query->getResultArray() as $row) {
        $items[] = $row['ITEM_NAME'];
      }

      $count = count($items);

      return $this->respond([
        'count' => $count,
        'items'  => $items
      ], 200);

    }

    //당첨자 상세
    public  function winnerDetail($seq)
    {
      $db = \Config\Database::connect();

      // 이벤트 + 아이템 목록 조인 조회
      $builder = $db->table('EVT_LIST E');
      $builder->join('EVT_ITEM I', 'E.SEQ = I.EVT_SEQ', 'left');
      $builder->join('PARTICIPATION_LIST P', 'E.SEQ = P.EVT_SEQ', 'left');
      $builder->select(
        'E.SEQ, E.TITLE, E.STARTDATE, E.ENDDATE, E.REGDATE, ' .
        'I.ITEM_SEQ, I.ITEM_NAME AS ITEM_ITEM_NAME, I.WIN_QTY, I.WIN_RATE,' .
        'P.PART_SEQ, P.RANK, P.ITEM_NAME AS PART_ITEM_NAME, P.ID, P.NAME, P.PHONE, P.WINNER_DATE, P.RANK_INDEX, P.PRIVACY_AGREE, P.THIRDPARTY_AGREE'
      );
      $builder->where('E.SEQ', $seq);

      $rows = $builder->get()->getResultArray();

      if (empty($rows)) {
        return $this->respond(['status' => 'fail', 'message' => '해당 이벤트가 없습니다.'], 404);
      }

      // 이벤트(게시글) 정보와 아이템 배열로 가공하여 응답
      $event = [
        'seq' => $rows[0]['SEQ'],
        'title' => $rows[0]['TITLE'],
        'startdate' => date('Y-m-d', strtotime( $rows[0]['STARTDATE'])),
        'enddate' => date('Y-m-d', strtotime( $rows[0]['ENDDATE'])),
        'regdate' =>date('Y-m-d', strtotime( $rows[0]['REGDATE'])),
        'items' => [],
        'participations' => [],
        'participations_cal' => []
      ];

      // 중복방지용
      $itemSeqSet = [];
      $partSeqSet = [];

      foreach ($rows as $row) {
        // 아이템 중복 체크 및 추가
        if ($row['ITEM_SEQ'] !== null && !isset($itemSeqSet[$row['ITEM_SEQ']])) {
          $event['items'][] = [
            'item_seq' => $row['ITEM_SEQ'],
            'name' => $row['ITEM_ITEM_NAME'], // 반드시! EVT_ITEM 테이블의 컬럼명 별칭
            'qty' => $row['WIN_QTY'],
            'rate' => $row['WIN_RATE']
          ];
          $itemSeqSet[$row['ITEM_SEQ']] = true;
        }


        // 참여자 중복 체크 및 추가
        if ($row['PART_SEQ'] !== null && !isset($partSeqSet[$row['PART_SEQ']])) {
          $event['participations'][] = [
            'part_seq' => $row['PART_SEQ'],
            'rank' => $row['RANK'],
            'item_name' => $row['PART_ITEM_NAME'],
            'id' => $row['ID'],
            'name' => $row['NAME'],
            'phone' => $row['PHONE'],
            'winner_date' => $row['WINNER_DATE'] = date('Y-m-d', strtotime($row['WINNER_DATE'])),
            'rank_index' => $row['RANK_INDEX'],
            'privacy_agree' => $row['PRIVACY_AGREE'],
            'thirdparty_agree' => $row['THIRDPARTY_AGREE']
          ];
          $partSeqSet[$row['PART_SEQ']] = true;
        }
      }


      // 중복되는 rank에서 part_seq가 가장 낮은 값만 participations_cal에 담기
      // 유니크 참여자 배열 만들기
      $participations = [];
      foreach ($rows as $row) {
          if (
              !array_key_exists('PART_SEQ', $row) ||
              !array_key_exists('RANK', $row) ||
              $row['PART_SEQ'] === null ||
              $row['RANK'] === null ||
              $row['RANK'] == 0
          ) {
              continue;
          }
          $participations[$row['PART_SEQ']] = $row;
      }

      // 등수별 인원수 카운트
      $rankCounts = [];
      foreach ($participations as $part) {
          $rank = $part['RANK'];
          if (!isset($rankCounts[$rank])) {
              $rankCounts[$rank] = 0;
          }
          $rankCounts[$rank]++;
      }

      // 중복 등수에서 part_seq가 가장 낮은 값만 participations_cal에 담기 (참여자 기준)
      $rankMinPartSeq = [];
      foreach ($participations as $part) {
          $rank = $part['RANK'];
          $partSeq = $part['PART_SEQ'];
          if (!isset($rankMinPartSeq[$rank]) || $partSeq < $rankMinPartSeq[$rank]['part_seq']) {
              $rankMinPartSeq[$rank] = [
                  'part_seq' => $partSeq,
                  'rank' => $part['RANK'],
                  'item_name' => $part['PART_ITEM_NAME'],
                  'id' => $part['ID'],
                  'name' => $part['NAME'],
                  'phone' => $part['PHONE'],
                  'winner_date' => $part['WINNER_DATE'],
                  'rank_index' => $part['RANK_INDEX'],
                  'privacy_agree' => $part['PRIVACY_AGREE'],
                  'thirdparty_agree' => $part['THIRDPARTY_AGREE'],
                  'count' => $rankCounts[$rank]
              ];
          }
      }
      $event['participations_cal'] = array_values($rankMinPartSeq);

      return $this->respond($event, 200);
    }

    //참여자 리스트
    public function getParticipationByItem()
    {
      $db = \Config\Database::connect();
      $request = $this->request->getJSON(true);

      // 파라미터 추출
      $seq = isset($request['seq']) ? $request['seq'] : null;
      $itemName = isset($request['item_name']) ? $request['item_name'] : null;

      if (empty($seq)) {
        return $this->respond(['status' => 'fail', 'message' => 'seq는 필수입니다.'], 400);
      }

      // PARTICIPATION_LIST에서 EVT_SEQ와 ITEM_NAME으로 필터링
      $builder = $db->table('PARTICIPATION_LIST');
      $builder->where('EVT_SEQ', $seq);
      if (!empty($itemName)) {
        $builder->where('ITEM_NAME', $itemName);
      }

      $filterList = $builder->get()->getResultArray();

      // 키를 모두 소문자로 변환
      $filterListLower = [];
      foreach ($filterList as $row) {
        $filterListLower[] = array_change_key_case($row, CASE_LOWER);
      }


      return $this->respond([
        'status' => 'success',
        'list' => $filterListLower
      ], 200);
    }

    // 이벤트 참가 여부 체크
    public function matchedUser()
    {
      $data = $this->request->getJSON(true);

      $seq = $data['seq'] ?? null;
      $name = $data['name'] ?? null;
      $phone = $data['phone'] ?? null;


      if (!$seq || !$name || !$phone) {
        return $this->fail('필수 값이 누락되었습니다.', 400);
      }


      $db = \Config\Database::connect();
      $builder = $db->table('PARTICIPATION_LIST');


      $existing = $builder
        ->where('EVT_SEQ', $seq)
        ->where('NAME', $name)
        ->where('PHONE', $phone)
        ->get()
        ->getRowArray();

      if ($existing) {
        // 동일한 사람이 이미 존재할 경우
        return $this->respond([
          'result' => 'matched'
        ]);
      }

      $phoneSame = $builder
        ->where('EVT_SEQ', $seq)
        ->where('NAME !=', $name)
        ->where('PHONE', $phone)
        ->get()
        ->getRowArray();

      if ($phoneSame) {
        return $this->respond([
          'result' => 'phonesame'
        ]);
      }

      // 일치하는 정보가 없을 때 (필요에 따라 처리)
      return $this->respond([
        'result' => 'not_found'
      ]);

    }
  }