DELIMITER //

CREATE OR REPLACE PROCEDURE orm_exec_insert_v2(
  IN p_tablename VARCHAR(200),  -- tablename
  IN p_pk VARCHAR(100),         -- primary key(for update delete)
  IN p_action VARCHAR(20),      -- CRUDP
  IN p_uuid VARCHAR(100),
  IN p_userid VARCHAR(100)
)
/*
  Function   : orm_api_v2 [新增]的核心程式, 智慧的組出相應的 sql
  Description: 關於 Master-Detail 的補充說明
  Build Date : 2023/12/16
  Modified for MariaDB
*/
BEGIN
  DECLARE v_maxcount INT;
  DECLARE v_currid INT;
  DECLARE v_is_md SMALLINT;
  DECLARE v_is_excel SMALLINT;
  DECLARE v_maxid INT;
  DECLARE v_excel_id INT;
  DECLARE v_cnt INT;
  DECLARE v_cn_field VARCHAR(100);
  DECLARE v_cd_field VARCHAR(100);
  DECLARE v_billno VARCHAR(20);
  DECLARE v_sub_table VARCHAR(100);
  DECLARE v_sql TEXT;
  DECLARE v_max_no VARCHAR(20);
  DECLARE v_maxcnt INT;
  
  -- step 1: 判斷狀態: 是否 master-detail 多筆資料?
  SELECT MAX(parent_id) INTO v_maxcount FROM orm_json_tmp WHERE uuid = p_uuid;
  
  -- @is_md 是使用 input-table template 用的判斷
  SELECT COUNT(*), IFNULL(MAX(parent_id), 0) 
  INTO v_is_md, v_maxid 
  FROM orm_json_tmp 
  WHERE uuid = p_uuid AND json_key = 'details' AND valuetype = 'array';
  
  SELECT COUNT(*), IFNULL(MAX(parent_id), 0) 
  INTO v_is_excel, v_excel_id 
  FROM orm_json_tmp 
  WHERE uuid = p_uuid AND json_key = 'excel' AND valuetype = 'array';
  
  -- step 2: update/insert create_user (僅允許一次一筆資料)
  SET v_cn_field = 'create_user';
  SET v_cd_field = 'create_date';
  
  -- Check if create_user column exists
  SELECT COUNT(*) INTO v_cnt 
  FROM information_schema.columns 
  WHERE table_name = p_tablename AND column_name = v_cn_field;
  
  IF v_cnt > 0 THEN
    SELECT COUNT(*) INTO v_cnt FROM orm_json_tmp WHERE uuid = p_uuid AND json_key = v_cn_field;
    IF v_cnt = 0 THEN
      INSERT INTO orm_json_tmp (uuid, parent_id, json_key, json_value, ValueType) 
      VALUES (p_uuid, v_maxcount, v_cn_field, p_userid, 'string');
    ELSE 
      UPDATE orm_json_tmp SET json_value = p_userid 
      WHERE uuid = p_uuid AND json_key = v_cn_field;
    END IF;
  END IF;
  
  -- Check if create_date column exists    
  SELECT COUNT(*) INTO v_cnt 
  FROM information_schema.columns 
  WHERE table_name = p_tablename AND column_name = v_cd_field;
  
  IF v_cnt > 0 THEN
    SELECT COUNT(*) INTO v_cnt FROM orm_json_tmp WHERE uuid = p_uuid AND json_key = v_cd_field;
    IF v_cnt = 0 THEN
      INSERT INTO orm_json_tmp (uuid, parent_id, json_key, json_value, ValueType) 
      VALUES (p_uuid, v_maxcount, v_cd_field, DATE_FORMAT(NOW(), '%Y-%m-%d'), 'string');
    ELSE 
      UPDATE orm_json_tmp SET json_value = DATE_FORMAT(NOW(), '%Y-%m-%d') 
      WHERE uuid = p_uuid AND json_key = v_cd_field;
    END IF;
  END IF;

  -- step 3: 針對 m-d 的單號前置處理(針對 billno=自動編碼, 給定新的單號)
  SELECT COUNT(*) INTO v_cnt 
  FROM orm_json_tmp 
  WHERE uuid = p_uuid AND json_key = 'billno' 
    AND (json_value LIKE '%自動%' OR json_value LIKE '%Auto%');
  
  IF v_cnt > 0 THEN
    -- hard-code
    IF p_pk = '' OR p_tablename LIKE '%_d%' THEN
      -- master-detail 的 detail insert
      SET v_max_no = CONCAT(SUBSTRING(p_tablename, 4, 6), SUBSTRING(p_userid, 1, 6));
    ELSE
      -- 先取得今天最大號
      SET @sql = CONCAT('SELECT MAX(billno) INTO @max_billno FROM ', p_tablename, 
                       ' WHERE DATE(billdate) = CURDATE()');
      PREPARE stmt FROM @sql;
      EXECUTE stmt;
      DEALLOCATE PREPARE stmt;
      
      -- 計算新單號 (需要實現 sys_next_no 函數)
      SET v_max_no = sys_next_no(@max_billno);
  
      -- 紀錄新增單號
      DELETE FROM sys_new_billno WHERE create_time < DATE_SUB(NOW(), INTERVAL 3 DAY);
      
      -- 防錯
      SELECT COUNT(*) INTO v_maxcnt 
      FROM sys_new_billno 
      WHERE tablename = p_tablename AND login_user = p_userid;
      
      IF v_maxcnt > 0 THEN
        UPDATE sys_new_billno SET billno = v_max_no 
        WHERE tablename = p_tablename AND login_user = p_userid;
      ELSE 
        INSERT INTO sys_new_billno VALUES (p_tablename, p_userid, v_max_no, NOW());
      END IF;
    END IF;
  
    UPDATE orm_json_tmp SET json_value = v_max_no 
    WHERE uuid = p_uuid AND json_key = 'billno' 
      AND (json_value LIKE '%自動%' OR json_value LIKE '%Auto%');
  END IF;

  -- master-detail
  IF v_is_md > 0 THEN
    -- 寫入 master 一筆
    CALL orm_api_kernel_v2(p_tablename, p_pk, p_action, p_uuid, v_maxcount);
    
    -- 取得表頭的單號
    SELECT billno INTO v_billno 
    FROM sys_new_billno 
    WHERE tablename = p_tablename AND login_user = p_userid;
    
    -- 寫入 details 多筆
    SELECT detail_table INTO v_sub_table 
    FROM zen_function 
    WHERE maintable = p_tablename 
    LIMIT 1;
    
    IF IFNULL(v_sub_table, '') = '' THEN
      SET v_sub_table = CONCAT(SUBSTRING(p_tablename, 1, LENGTH(p_tablename)-1), 'd');
    END IF;
  
    -- 多筆 detail 資料寫入
    SET v_currid = 1;
    WHILE v_currid < v_maxid DO
      -- 執行核心程式
      CALL orm_api_kernel_v2(v_sub_table, p_pk, p_action, p_uuid, v_currid);
      
      -- 取得下一筆資料
      SET v_currid = v_currid + 1;
    END WHILE;
  ELSEIF v_is_excel > 0 THEN
    -- excel 多筆資料匯入
    SET v_currid = 1;
    WHILE v_currid < v_excel_id-1 DO
      -- 執行核心程式
      CALL orm_api_kernel_v2(p_tablename, p_pk, p_action, p_uuid, v_currid);
      
      -- 取得下一筆資料
      SET v_currid = v_currid + 1;
    END WHILE;
  ELSEIF v_maxcount > 1 THEN
    -- 多筆資料寫入
    SET v_currid = 1;
    WHILE v_currid <= v_maxcount DO
      -- 執行核心程式
      CALL orm_api_kernel_v2(p_tablename, p_pk, p_action, p_uuid, v_currid);
      
      -- 取得下一筆資料
      SET v_currid = v_currid + 1;
    END WHILE;
  ELSE 
    CALL orm_api_kernel_v2(p_tablename, p_pk, p_action, p_uuid, 1);
  END IF;
END //

DELIMITER ;