<?php

namespace App\Http\Repositories;

use App\Models\Chemical_mix;
use Illuminate\Support\Facades\DB;

class ChemicalMixRepository
{

    function __construct(protected Chemical_mix $Cm) {}

    function store($data)
    {
        $this->Cm->insert($data);
    }
    function create($data)
    {
        $this->Cm->create($data);
    }
    function update($data, $ord_id): void
    {
        // 使用資料庫事務，確保所有操作的原子性。
        // 如果任何操作失敗，所有已執行的操作都會被回滾。
        DB::transaction(function () use ($data, $ord_id) {
            // 1. 取得現有與此 ord_id 相關的所有 Chemical_mix 記錄。
            //    使用 keyBy('id') 將集合的鍵值設為記錄的 ID，方便後續查找。
            $existing_records = $this->Cm->where('ord_id', $ord_id)->get()->keyBy('id');

            // 2. 從傳入的 $data 中，收集所有包含 'id' 的項目之 ID 列表。
            //    filter() 用於移除任何空值或 null (例如，如果 pluck 返回 null)。
            $incoming_ids = collect($data)->pluck('id')->filter()->toArray();

            // 3. 處理刪除：找出那些在資料庫中存在但不在傳入 $data 中的記錄的 ID。
            //    existing_records->keys() 取得所有現有記錄的 ID。
            //    diff($incoming_ids) 找出差異部分，即需要刪除的 ID。
            $ids_to_delete = $existing_records->keys()->diff($incoming_ids);

            // 如果有需要刪除的 ID，則執行批量刪除操作。
            if ($ids_to_delete->isNotEmpty()) {
                $this->Cm->whereIn('id', $ids_to_delete)->delete();
            }

            // 4. 處理新增或更新傳入的資料。
            foreach ($data as $item) {
                // 確保每個項目都包含 ord_id，無論是新增還是更新。
                $values_to_update_or_create = $item;
                $values_to_update_or_create['ord_id'] = $ord_id;

                // 檢查項目是否包含 'id'。如果包含，則嘗試更新；否則，視為新增。
                if (isset($item['id']) && $item['id']) {
                    $id = $item['id'];
                    // 從已取得的現有記錄中查找此 ID 對應的記錄。
                    $record_exists = $existing_records->get($id);

                    // 如果記錄存在於資料庫中 (且屬於此 ord_id)
                    if ($record_exists) {
                        // 檢查傳入的資料與現有記錄是否有實際變更。
                        $has_changes = false;
                        foreach ($values_to_update_or_create as $key => $value) {
                            // 排除 'id' 欄位本身的比較，因為 id 不會變更。
                            // 使用 getAttribute() 方法來安全地訪問模型屬性，這比直接訪問屬性更健壯。
                            // 確保鍵存在於模型屬性中，且值是否不同。
                            if ($key !== 'id' && $record_exists->offsetExists($key) && $record_exists->getAttribute($key) !== $value) {
                                $has_changes = true;
                                break; // 只要找到一個不同，就標記有變更並跳出迴圈。
                            }
                        }

                        // 如果有任何欄位有實際變更，則執行更新操作。
                        // 這包含了您希望的 CAS_NO 變更判斷，因為 CAS_NO 也是其中一個會被比較的欄位。
                        if ($has_changes) {
                            $this->Cm->where('id', $id)->update($values_to_update_or_create);
                        }
                    } else {
                        // 如果傳入的 $item 有 id，但這個 id 不存在於此 ord_id 的現有記錄中，
                        // 這通常表示這是一個錯誤的 id 或者是一個需要新增的項目 (儘管帶有 id)。
                        // 在此情境下，我們將其視為新增。
                        $this->Cm->create($values_to_update_or_create);
                    }
                } else {
                    // 如果 $item 沒有 'id'，則直接建立新記錄。
                    $this->Cm->create($values_to_update_or_create);
                }
            }
        });
    }

    function destory($id)
    {
        return $this->Cm->where('ord_id', $id)->delete();
    }
}
