<?php
// ============================================================
// BalanceLabForm  — implements ILabForm
//
// Fields NOT stored here (pulled from existing tables at query time):
//   laboratory_number  → requests.request_number
//   item_calibrated    → equipment.equipment_name
//   customer_details   → companies.company_name
//   serial_number      → equipment.serial_number
//   manufacturer       → equipment.manufacturer
//   type               → equipment.model
// ============================================================
class BalanceLabForm implements ILabForm {

    private const FIELDS = [
        // Admin A — balance-specific only
        'certification_number','accreditation','max_capacity','unit',
        'min_capacity','unitsec','test_method','place_of_test',
        'high_air_circulation','high_vibration',
        'temp_during_cal_start','temp_during_cal_end',
        // Admin B
        'applied_load','deviation','preloading_executed','balance_adjusted',
        'chng_temp','accuracy_class_of_weight','lab_temperature','site_temperature',
        'time_waited','calibrated_by','checked_by','comments',
        // Test of Error Indicator
        'nominal_value_0','load_0','reference_weight_0','indication_0','deviation_of_indication_0',
        'nominal_value_25','load_25','reference_weight_25','indication_25','deviation_of_indication_25',
        'nominal_value_50','load_50','reference_weight_50','indication_50','deviation_of_indication_50',
        'nominal_value_75','load_75','reference_weight_75','indication_75','deviation_of_indication_75',
        'nominal_value_100','load_100','reference_weight_100','indication_100','deviation_of_indication_100',
        // MPE / Uncertainty of Standard
        'mpe_1','mpe_2','mpe_3','mpe_4','mpe_5',
        'u_of_std_value_1','u_of_std_value_2','u_of_std_value_3','u_of_std_value_4','u_of_std_value_5',
        // Repeatability
        'applied_load_rt',
        'repeatability1','repeatability2','repeatability3','repeatability4','repeatability5',
        'repeat_value_1','repeat_value_2','repeat_value_3','repeat_value_4','repeat_value_5',
        'standard_deviation',
        // Eccentricity
        'applied_load_et',
        'EC_Indication1_Centre','EC_Deviation_Centre','EC_Abs_Deviation_Centre',
        'EC_Indication_FL','EC_Deviation_FL','EC_Abs_Deviation_FL',
        'EC_Indication_BL','EC_Deviation_BL','EC_Abs_Deviation_BL',
        'EC_Indication_BR','EC_Deviation_BR','EC_Abs_Deviation_BR',
        'EC_Indication_FR','EC_Deviation_FR','EC_Abs_Deviation_FR',
        'max_difference',
        // Uncertainty Calculation
        'Idig_1','Idig_2','Idig_3','Idig_4','Idig_5',
        'u_IdigL_1','u_IdigL_2','u_IdigL_3','u_IdigL_4','u_IdigL_5',
        'Iecc_value_1','Iecc_value_2','Iecc_value_3','Iecc_value_4','Iecc_value_5',
        'u_omc_1','u_omc_2','u_omc_3','u_omc_4','u_omc_5',
        'u_mB_1','u_mB_2','u_mB_3','u_mB_4','u_mB_5',
        'u_mD_1','u_mD_2','u_mD_3','u_mD_4','u_mD_5',
        'u_mconv_1','u_mconv_2','u_mconv_3','u_mconv_4','u_mconv_5',
        'u_E_1','u_E_2','u_E_3','u_E_4','u_E_5',
        'Veff_value_1','Veff_value_2','Veff_value_3','Veff_value_4','Veff_value_5',
        'K_value_1','K_value_2','K_value_3','K_value_4','K_value_5',
        'U_value_1','U_value_2','U_value_3','U_value_4','U_value_5',
    ];

    private const DATE_FIELDS = ['calibration_date','calibrated_date','date_checked','due_date'];

    public function getTableSchema(): string {
        return file_get_contents(__DIR__ . '/../../../database/balance_schema.sql');
    }

    public function validate(array $post): array {
        $errors = [];
        if (empty(trim($post['certification_number'] ?? ''))) $errors[] = 'Certificate number is required.';
        if (empty($post['unit'] ?? ''))                       $errors[] = 'Unit (max capacity) is required.';
        if (empty($post['calibration_date'] ?? ''))           $errors[] = 'Calibration date is required.';
        if (empty($post['place_of_test'] ?? ''))              $errors[] = 'Place of test is required.';
        return $errors;
    }

    public function save(int $requestId, int $officerId, int $labId, array $post): int {
        $db     = Database::getInstance();
        $s      = fn($v) => htmlspecialchars(strip_tags(trim((string)$v)), ENT_QUOTES, 'UTF-8');
        $status = ($post['form_status'] ?? 'draft') === 'submitted' ? 'submitted' : 'draft';

        $data = ['form_status' => $status];
        foreach (self::FIELDS as $field) {
            $data[$field] = $s($post[$field] ?? '');
        }
        foreach (self::DATE_FIELDS as $field) {
            $raw = trim($post[$field] ?? '');
            $data[$field] = $raw ?: null;
        }

        $existing = $this->load($requestId);
        if ($existing) {
            $sets   = implode(', ', array_map(fn($k) => "`$k` = ?", array_keys($data)));
            $vals   = array_values($data);
            $vals[] = $existing['form_id'];
            $db->prepare("UPDATE balance_lab_forms SET $sets WHERE form_id = ?")->execute($vals);
            return $existing['form_id'];
        }

        $data['request_id'] = $requestId;
        $data['officer_id'] = $officerId;
        $data['lab_id']     = $labId;
        $cols   = implode(', ', array_map(fn($k) => "`$k`", array_keys($data)));
        $places = implode(', ', array_fill(0, count($data), '?'));
        $db->prepare("INSERT INTO balance_lab_forms ($cols) VALUES ($places)")->execute(array_values($data));
        return (int)$db->lastInsertId();
    }

    public function load(int $requestId): ?array {
        $db   = Database::getInstance();
        $stmt = $db->prepare('SELECT * FROM balance_lab_forms WHERE request_id = ?');
        $stmt->execute([$requestId]);
        return $stmt->fetch() ?: null;
    }

    public function isSubmitted(array $formData): bool {
        return ($formData['form_status'] ?? '') === 'submitted';
    }
}
