﻿DELIMITER $$

CREATE PROCEDURE `sp_sync_resource_info_from_scan`( -- 새 이름으로 생성
    IN p_admin_user_id INT,
    IN p_actor_description VARCHAR(100),
    IN p_user_account_name VARCHAR(255), -- 사용자 계정명
    IN p_category VARCHAR(100),          -- 스캔된 카테고리명
    IN p_manufacturer VARCHAR(100),      -- 스캔된 제조사
    IN p_resource_name VARCHAR(100),     -- 스캔된 제품명
    IN p_serial_num VARCHAR(200),        -- 스캔된 시리얼 번호
    IN p_spec_value VARCHAR(255),        -- 스캔된 사양 값 (문자열)
    IN p_spec_unit VARCHAR(10),          -- 스캔된 사양 단위 (문자열)
    IN p_detected_by VARCHAR(50),        -- 스캔 도구 정보 등 (현재 로직 미사용)
    IN p_change_type TINYINT,            -- 1: ADD(추가/할당), 2: DELETE(할당 해제)
    OUT p_result_message VARCHAR(255)
)
  COMMENT '스캔 정보 기반 자산 정보 동기화(추가/할당/해제) 및 로그 (Rust 연동용)'
BEGIN
  DECLARE v_user_id BIGINT DEFAULT NULL;
  DECLARE v_category_id TINYINT UNSIGNED;
  DECLARE v_spec_unit_id TINYINT UNSIGNED DEFAULT NULL;
  DECLARE v_now DATETIME DEFAULT NOW();
  DECLARE v_existing_resource_id BIGINT;
  DECLARE v_common_log VARCHAR(255);
  DECLARE v_new_spec_value DECIMAL(10, 2) DEFAULT NULL;
  DECLARE v_comments_to_set VARCHAR(200) DEFAULT NULL;
  DECLARE v_existing_user_id BIGINT; -- 기존 자산의 할당 사용자 ID
  DECLARE v_is_locked BOOLEAN DEFAULT FALSE;

  DECLARE EXIT HANDLER FOR SQLEXCEPTION
  BEGIN
    GET DIAGNOSTICS CONDITION 1 @errno = MYSQL_ERRNO, @sqlstate = RETURNED_SQLSTATE, @text = MESSAGE_TEXT;
    ROLLBACK; SET p_result_message = CONCAT('처리 중 오류 발생 (', @errno, '/', @sqlstate, '): ', @text);
  END;

  -- 입력값 검증
  IF p_admin_user_id IS NULL AND p_actor_description IS NULL THEN
    SET p_result_message = '작업 주체 정보(관리자 ID 또는 프로세스 설명)는 필수입니다.';
  ELSE
    -- 트랜잭션 시작
    START TRANSACTION;
    SET p_result_message = NULL;

    -- 카테고리/단위 ID 매핑
    IF p_category = 'VGA' THEN 
      SET p_category = 'GPU';
    END IF;
	  SELECT category_id INTO v_category_id FROM resource_category WHERE category_name = p_category LIMIT 1;
    IF v_category_id IS NULL THEN
       SET v_category_id = 0; -- 기본값 0 또는 다른 처리
       SET p_result_message = CONCAT('주의: 알 수 없는 카테고리(', p_category, ')가 ID 0으로 처리됨. ');
    END IF;
    SET v_spec_unit_id = CASE LOWER(TRIM(p_spec_unit)) WHEN 'mhz' THEN 1 WHEN 'mb' THEN 2 WHEN 'gb' THEN 3 WHEN 'tb' THEN 4 WHEN 'pb' THEN 5 WHEN 'inch' THEN 6 ELSE NULL END;

    -- 사용자 ID 조회
    SELECT user_id INTO v_user_id FROM user_info WHERE LOWER(account_name) = LOWER(p_user_account_name) LIMIT 1;
    SET v_common_log = CONCAT(p_user_account_name, ' - ', p_category, ' (SN:', IFNULL(p_serial_num, 'N/A'), ')');

    -- 스펙 값 처리
    IF p_change_type = 1 AND p_spec_value IS NOT NULL AND p_spec_value != 'N/A' THEN
      IF p_spec_value REGEXP '^[0-9]+([.][0-9]+)?$' THEN SET v_new_spec_value = CAST(p_spec_value AS DECIMAL(10, 2));
      ELSE SET p_result_message = CONCAT(IFNULL(p_result_message, ''), '주의: Spec 값 "', p_spec_value, '"는 유효 숫자가 아님. '); END IF;
    END IF;

    -- === 변경 타입 분기 ===
    IF p_change_type = 1 THEN -- ADD (자산 추가 또는 사용자 할당)
      IF p_serial_num IS NULL OR p_serial_num = '' THEN
         ROLLBACK; SET p_result_message = CONCAT(IFNULL(p_result_message,''), '추가/할당 실패: 시리얼 번호는 필수입니다. ', v_common_log);
      ELSE
        -- 시리얼 번호로 기존 자산 조회
        SELECT resource_id, user_id INTO v_existing_resource_id, v_existing_user_id FROM resource_info WHERE serial_num = p_serial_num LIMIT 1;

        IF v_existing_resource_id IS NOT NULL THEN -- 자산 존재
          IF v_is_locked = TRUE THEN -- ★★★ 자산이 잠겨있는 경우 ★★★
            SET p_result_message = CONCAT(IFNULL(p_result_message, ''), '자산이 잠겨있어 스캔 정보로 업데이트하지 않음: ', v_common_log);
          ELSE
            IF v_existing_user_id IS NULL AND v_user_id IS NOT NULL THEN -- 미할당 자산 -> 사용자 할당
                UPDATE resource_info SET user_id = v_user_id, update_date = v_now WHERE resource_id = v_existing_resource_id;
                INSERT INTO log_update_resource (log_date, admin_user_id, actor_description, resource_id, user_id) VALUES (v_now, p_admin_user_id, p_actor_description, v_existing_resource_id, v_user_id);
                SET p_result_message = CONCAT(IFNULL(p_result_message, ''), '기존 미할당 자산에 사용자 할당 완료: ', v_common_log);
                COMMIT;
            ELSEIF v_existing_user_id = v_user_id THEN -- 이미 해당 사용자에게 할당됨
                 SET p_result_message = CONCAT(IFNULL(p_result_message, ''), '이미 사용자에게 할당된 동일 자산: ', v_common_log); COMMIT;
            ELSE -- 다른 사용자 할당 or 중복 추가 시도
                 SET p_result_message = CONCAT(IFNULL(p_result_message, ''), '이미 등록된 시리얼 번호 (다른 사용자 또는 중복): ', v_common_log); COMMIT;
            END IF;
          END IF;
        ELSE -- 자산 미존재 (신규 추가)
            IF v_category_id = 0 THEN -- 유효하지 않은 카테고리 (선택적)
                ROLLBACK; SET p_result_message = CONCAT(IFNULL(p_result_message,''), '추가 실패: 유효한 카테고리 정보가 필요합니다.');
            ELSE
                IF v_user_id IS NULL THEN SET v_comments_to_set = CONCAT('Detected from Host: ', p_user_account_name); END IF;
                INSERT INTO resource_info (category_id, manufacturer, resource_name, serial_num, spec_value, spec_unit, user_id, comments, register_date, is_locked) VALUES (v_category_id, p_manufacturer, p_resource_name, p_serial_num, v_new_spec_value, v_spec_unit_id, v_user_id, v_comments_to_set, v_now, FALSE);
                SET v_existing_resource_id = LAST_INSERT_ID();
                INSERT INTO log_add_resource (log_date, admin_user_id, actor_description, resource_id, category_id, resource_code, manufacturer, resource_name, serial_num, spec_value, spec_unit, user_id, comments, purchase_date, register_date) SELECT v_now, p_admin_user_id, p_actor_description, r.resource_id, r.category_id, r.resource_code, r.manufacturer, r.resource_name, r.serial_num, r.spec_value, r.spec_unit, r.user_id, r.comments, r.purchase_date, r.register_date FROM resource_info r WHERE r.resource_id = v_existing_resource_id;
                SET p_result_message = CONCAT(IFNULL(p_result_message, ''), '신규 등록 완료: ', v_common_log);
                COMMIT;
            END IF; -- 카테고리 유효성 IF 종료
        END IF; -- 자산 존재 IF 종료
      END IF; -- 시리얼 번호 유효성 IF 종료

    ELSEIF p_change_type = 2 THEN -- DELETE (사용자 할당 해제)
      IF v_user_id IS NULL THEN
         ROLLBACK; SET p_result_message = CONCAT(IFNULL(p_result_message,''), '할당 해제 실패: 기준 사용자 ID를 찾을 수 없습니다. (', p_user_account_name, ')');
      ELSEIF p_serial_num IS NULL OR p_serial_num = '' THEN
         ROLLBACK; SET p_result_message = CONCAT(IFNULL(p_result_message,''), '할당 해제 실패: 기준 시리얼 번호가 없습니다. ', v_common_log);
      ELSE
        SELECT resource_id, is_locked INTO v_existing_resource_id, v_is_locked FROM resource_info WHERE user_id = v_user_id AND serial_num = p_serial_num LIMIT 1;
        
        IF v_existing_resource_id IS NULL THEN
          SET p_result_message = CONCAT(IFNULL(p_result_message, ''), '할당 해제 대상 없음 (사용자 + 시리얼 기준). ', v_common_log); COMMIT;
        ELSEIF v_is_locked = TRUE THEN
           SET p_result_message = CONCAT(IFNULL(p_result_message, ''), '자산이 잠겨있어 자동 할당 해제하지 않음: ', v_common_log); COMMIT;
        ELSE
          UPDATE resource_info SET user_id = NULL, update_date = v_now WHERE resource_id = v_existing_resource_id;
          INSERT INTO log_update_resource (log_date, admin_user_id, actor_description, resource_id, user_id) VALUES (v_now, p_admin_user_id, p_actor_description, v_existing_resource_id, NULL);
          SET p_result_message = CONCAT(IFNULL(p_result_message, ''), '사용자 할당 해제 완료: ', v_common_log);
          COMMIT;
        END IF; -- 할당 해제 대상 존재 IF 종료
      END IF; -- 파라미터 유효성 IF 종료

    ELSE -- 알 수 없는 타입
      SET p_result_message = CONCAT(IFNULL(p_result_message, ''), '알 수 없는 작업 타입: ', p_change_type); COMMIT;
    END IF; -- 변경 타입 IF 종료

  END IF; -- 작업 주체 검증 IF 종료

END
$$

DELIMITER ;