<?php

namespace App\Models;

use CodeIgniter\Model;

class VendorInfluencerStatusHistoryModel extends Model
{
    protected $table = 'VENDOR_INFLUENCER_STATUS_HISTORY';
    protected $primaryKey = 'SEQ';
    protected $useAutoIncrement = true;
    protected $returnType = 'array';
    protected $useSoftDeletes = false;
    protected $protectFields = true;
    protected $allowedFields = [
        'MAPPING_SEQ',
        'STATUS',
        'PREVIOUS_STATUS',
        'STATUS_MESSAGE',
        'CHANGED_BY',
        'CHANGED_DATE',
        'IS_CURRENT',
        'REG_DATE'
    ];

    // Dates
    protected $useTimestamps = false;
    protected $dateFormat = 'datetime';
    protected $createdField = 'REG_DATE';
    protected $updatedField = '';
    protected $deletedField = '';

    // Validation
    protected $validationRules = [
        'MAPPING_SEQ' => 'required|integer',
        'STATUS' => 'required|in_list[PENDING,APPROVED,REJECTED,CANCELLED,EXPIRED,TERMINATED]',
        'CHANGED_BY' => 'permit_empty|integer',  // required 제거, permit_empty로 변경
        'IS_CURRENT' => 'required|in_list[Y,N]'
    ];

    protected $validationMessages = [
        'MAPPING_SEQ' => [
            'required' => '매핑 SEQ는 필수입니다.',
            'integer' => '매핑 SEQ는 정수여야 합니다.'
        ],
        'STATUS' => [
            'required' => '상태는 필수입니다.',
            'in_list' => '유효하지 않은 상태입니다.'
        ],
        'CHANGED_BY' => [
            'integer' => '변경자 SEQ는 정수여야 합니다.'
        ],
        'IS_CURRENT' => [
            'required' => 'IS_CURRENT는 필수입니다.',
            'in_list' => 'IS_CURRENT는 Y 또는 N이어야 합니다.'
        ]
    ];

    protected $skipValidation = false;
    protected $cleanValidationRules = true;

    // Callbacks
    protected $allowCallbacks = true;
    protected $beforeInsert = ['beforeInsert'];
    protected $afterInsert = [];
    protected $beforeUpdate = [];
    protected $afterUpdate = [];
    protected $beforeFind = [];
    protected $afterFind = [];
    protected $beforeDelete = [];
    protected $afterDelete = [];

    /**
     * 상태 변경 전 처리
     */
    protected function beforeInsert(array $data)
    {
        // REG_DATE 자동 설정
        if (!isset($data['data']['REG_DATE'])) {
            $data['data']['REG_DATE'] = date('Y-m-d H:i:s');
        }
        
        // CHANGED_DATE 자동 설정
        if (!isset($data['data']['CHANGED_DATE'])) {
            $data['data']['CHANGED_DATE'] = date('Y-m-d H:i:s');
        }

        return $data;
    }

    /**
     * 특정 매핑의 현재 상태 조회
     */
    public function getCurrentStatus($mappingSeq)
    {
        return $this->where('MAPPING_SEQ', $mappingSeq)
                   ->where('IS_CURRENT', 'Y')
                   ->first();
    }

    /**
     * 특정 매핑의 상태 히스토리 조회
     */
    public function getStatusHistory($mappingSeq, $limit = 10)
    {
        return $this->where('MAPPING_SEQ', $mappingSeq)
                   ->orderBy('CHANGED_DATE', 'DESC')
                   ->limit($limit)
                   ->findAll();
    }

    /**
     * 상태 변경 (트랜잭션 포함) - Fallback 방식 우선 적용
     */
    public function changeStatus($mappingSeq, $newStatus, $statusMessage = '', $changedBy = null)
    {
        $db = \Config\Database::connect();
        $db->transStart();

        try {
            log_message('info', "상태 변경 시작: mappingSeq={$mappingSeq}, newStatus={$newStatus}");

            // CHANGED_BY 기본값 처리
            if ($changedBy === null) {
                $changedBy = 1;
                log_message('warning', 'CHANGED_BY가 null이므로 기본값 1로 설정');
            }

            // 1. 현재 상태 조회
            $currentStatus = $this->getCurrentStatus($mappingSeq);
            $previousStatus = $currentStatus ? $currentStatus['STATUS'] : null;

            log_message('info', "이전 상태: " . ($previousStatus ?: 'NULL') . " → 새 상태: {$newStatus}");

            // 2. 히스토리 테이블 방식 시도
            $historySuccess = false;
            
            try {
                // 기존 상태 비활성화
                if ($currentStatus) {
                    $updateSql = "UPDATE VENDOR_INFLUENCER_STATUS_HISTORY 
                                 SET IS_CURRENT = 'N' 
                                 WHERE MAPPING_SEQ = ? AND IS_CURRENT = 'Y'";
                    $db->query($updateSql, [$mappingSeq]);
                    log_message('info', "기존 상태 비활성화 완료");
                }

                // 새 히스토리 레코드 추가
                $historyData = [
                    'MAPPING_SEQ' => (int)$mappingSeq,
                    'STATUS' => $newStatus,
                    'PREVIOUS_STATUS' => $previousStatus,
                    'STATUS_MESSAGE' => $statusMessage ?: '',
                    'CHANGED_BY' => (int)$changedBy,
                    'IS_CURRENT' => 'Y',
                    'CHANGED_DATE' => date('Y-m-d H:i:s'),
                    'REG_DATE' => date('Y-m-d H:i:s')
                ];

                if ($this->validate($historyData)) {
                    $insertResult = $this->insert($historyData, false);
                    if ($insertResult) {
                        $historySuccess = true;
                        log_message('info', "히스토리 테이블 업데이트 성공: ID={$insertResult}");
                    }
                }

            } catch (\Exception $historyError) {
                log_message('warning', '히스토리 테이블 방식 실패: ' . $historyError->getMessage());
            }

            // 3. 히스토리 테이블 실패 시 메인 테이블 직접 업데이트 (Fallback)
            if (!$historySuccess) {
                log_message('info', '히스토리 테이블 실패 - 메인 테이블 직접 업데이트로 fallback');
                
                $mappingModel = new VendorInfluencerMappingModel();
                $mainUpdateData = [
                    'STATUS' => $newStatus,
                    'RESPONSE_MESSAGE' => $statusMessage,
                    'RESPONSE_DATE' => date('Y-m-d H:i:s'),
                    'APPROVED_BY' => $changedBy,
                    'MOD_DATE' => date('Y-m-d H:i:s')
                ];

                // TERMINATED 상태인 경우 종료일 추가
                if ($newStatus === 'TERMINATED') {
                    $mainUpdateData['PARTNERSHIP_END_DATE'] = date('Y-m-d H:i:s');
                }

                $mainUpdateResult = $mappingModel->update($mappingSeq, $mainUpdateData);
                
                if (!$mainUpdateResult) {
                    throw new \Exception('메인 테이블 업데이트도 실패');
                }

                log_message('info', '메인 테이블 직접 업데이트 성공 (Fallback)');
                
                // 트랜잭션 완료
                $db->transComplete();
                
                if ($db->transStatus() === false) {
                    throw new \Exception('트랜잭션 실패');
                }

                return 'main_table_update'; // 성공 표시
            }

            // 4. 히스토리 테이블 성공 시 메인 테이블 MOD_DATE도 업데이트
            try {
                $mappingModel = new VendorInfluencerMappingModel();
                $mappingModel->update($mappingSeq, ['MOD_DATE' => date('Y-m-d H:i:s')]);
            } catch (\Exception $mainUpdateError) {
                log_message('warning', '메인 테이블 MOD_DATE 업데이트 실패 (계속 진행): ' . $mainUpdateError->getMessage());
            }

            // 트랜잭션 완료
            $db->transComplete();

            if ($db->transStatus() === false) {
                throw new \Exception('상태 변경 트랜잭션 실패');
            }

            log_message('info', "상태 변경 완료: mappingSeq={$mappingSeq}");

            return $insertResult ?? 'fallback_success';

        } catch (\Exception $e) {
            $db->transRollback();
            log_message('error', '상태 변경 실패: ' . $e->getMessage());
            log_message('error', '실패한 파라미터: ' . json_encode([
                'mappingSeq' => $mappingSeq,
                'newStatus' => $newStatus,
                'statusMessage' => $statusMessage,
                'changedBy' => $changedBy
            ]));

            throw $e;
        }
    }

    /**
     * 특정 상태의 매핑 목록 조회
     */
    public function getMappingsByStatus($status, $isActive = true)
    {
        $builder = $this->builder();
        $builder->select('VENDOR_INFLUENCER_STATUS_HISTORY.*, VENDOR_INFLUENCER_MAPPING.*')
                ->join('VENDOR_INFLUENCER_MAPPING', 
                       'VENDOR_INFLUENCER_MAPPING.SEQ = VENDOR_INFLUENCER_STATUS_HISTORY.MAPPING_SEQ')
                ->where('VENDOR_INFLUENCER_STATUS_HISTORY.STATUS', $status)
                ->where('VENDOR_INFLUENCER_STATUS_HISTORY.IS_CURRENT', 'Y');
        
        if ($isActive) {
            $builder->where('VENDOR_INFLUENCER_MAPPING.IS_ACT', 'Y');
        }

        return $builder->get()->getResultArray();
    }

    /**
     * 벤더사별 상태 통계
     */
    public function getStatusStatsByVendor($vendorSeq)
    {
        $builder = $this->builder();
        return $builder->select('VENDOR_INFLUENCER_STATUS_HISTORY.STATUS, COUNT(*) as count')
                      ->join('VENDOR_INFLUENCER_MAPPING', 
                             'VENDOR_INFLUENCER_MAPPING.SEQ = VENDOR_INFLUENCER_STATUS_HISTORY.MAPPING_SEQ')
                      ->where('VENDOR_INFLUENCER_MAPPING.VENDOR_SEQ', $vendorSeq)
                      ->where('VENDOR_INFLUENCER_STATUS_HISTORY.IS_CURRENT', 'Y')
                      ->where('VENDOR_INFLUENCER_MAPPING.IS_ACT', 'Y')
                      ->groupBy('VENDOR_INFLUENCER_STATUS_HISTORY.STATUS')
                      ->get()
                      ->getResultArray();
    }

    /**
     * 인플루언서별 상태 통계
     */
    public function getStatusStatsByInfluencer($influencerSeq)
    {
        $builder = $this->builder();
        return $builder->select('VENDOR_INFLUENCER_STATUS_HISTORY.STATUS, COUNT(*) as count')
                      ->join('VENDOR_INFLUENCER_MAPPING', 
                             'VENDOR_INFLUENCER_MAPPING.SEQ = VENDOR_INFLUENCER_STATUS_HISTORY.MAPPING_SEQ')
                      ->where('VENDOR_INFLUENCER_MAPPING.INFLUENCER_SEQ', $influencerSeq)
                      ->where('VENDOR_INFLUENCER_STATUS_HISTORY.IS_CURRENT', 'Y')
                      ->where('VENDOR_INFLUENCER_MAPPING.IS_ACT', 'Y')
                      ->groupBy('VENDOR_INFLUENCER_STATUS_HISTORY.STATUS')
                      ->get()
                      ->getResultArray();
    }
} 