<?php

namespace App\Controllers;

use App\Controllers\BaseController;
use CodeIgniter\HTTP\ResponseInterface;
use CodeIgniter\API\ResponseTrait;
use App\Models\ProductTempModel;
use DateTime;

class Key extends BaseController
{
    use ResponseTrait;

    public function index() {
        $publicKeyPath = WRITEPATH . 'key/public_key.pem';

        if (file_exists($publicKeyPath)) {
            //$publicKey = trim(file_get_contents($publicKeyPath));
            $publicKey = file_get_contents($publicKeyPath);
            return $this->respond([
                'publicKey' => $publicKey
            ]);
        } else {
            return $this->failNotFound('Public key not found');
        }
    }

    public function data() {
        $productTempModel = new ProductTempModel;

        $rawData = $this->request->getBody();
        $result = json_decode($rawData, true);
        
        $encryptedKeyIv = $result['encryptedKeyIv'];
        $encryptedKeyIv = base64_decode($encryptedKeyIv);
        $encryptedData = $result['encryptedData'];
        $clientChecksum = $result['checksum'];

        $privateKeyPath = WRITEPATH . 'key/private_key.pem';
        $privateKey = file_get_contents($privateKeyPath);
        $privateKeyResource = openssl_pkey_get_private($privateKey);

        $decryptedMessage = '';
        $result = openssl_private_decrypt($encryptedKeyIv, $decryptedMessage, $privateKeyResource, OPENSSL_PKCS1_OAEP_PADDING);

        if ($result) {
            $aesKey = substr($decryptedMessage, 0, 32);
            $aesIv = substr($decryptedMessage, 32, 16);
            $decryptedBytes = openssl_decrypt($encryptedData, 'aes-256-cbc', $aesKey, 0, $aesIv);
            $serverChecksum = hash('sha256', $decryptedBytes);
            $decryptedData = json_decode($decryptedBytes, true);
            $locationStartDate = $decryptedData['locationstartdate'];

            $warrantyStartDate = DateTime::createFromFormat('Ymd', $locationStartDate);
            if ($warrantyStartDate) {
                $warrantyEndDate = clone $warrantyStartDate;
                $warrantyEndDate->modify('+1 year');
            
                $formattedWarrantyEndDate = $warrantyEndDate->format('Y-m-d');
            } else {
                $formattedWarrantyEndDate = null;
            }

            if ($clientChecksum !== $serverChecksum) {
                return $this->fail('Checksum check failed');
            } else {
                $logQuery = [];
                $db = \Config\Database::connect();
                $db->transStart();
                foreach ($decryptedData['items'] as $value) {
                    $data = [
                        'productnumber' => $value['productnumber'],
                        'productname' => $value['productname'],
                        'catalognumber' => $value['catalognumber'],
                        'siteid' => 1,
                        'locationstartdate' => $locationStartDate,
                        'locationenddate' => NULL,
                        'installationdate' => NULL,
                        'warrantystartdate' => $locationStartDate,
                        'warrantyenddate' => $formattedWarrantyEndDate,
                        'active' => 'N', 
                        'owner' => 1,
                        'statusservice' => 2,
                        'statusparts' => '',
                        'userid' => 'SES^' . $decryptedData['userid'],
                        'reference' => $decryptedData['reference'],
                        'logdate' => $decryptedData['logdate'],
                    ];

                    if ($productTempModel->save($data)) {
                        $logQuery[] = [
                            'item' => $value['catalognumber'],
                            'status' => 'success',
                            'message' => 'Item saved successfully'
                        ];
                    } else {
                        $errors = $productTempModel->errors();
                        $logQuery[] = [
                            'item' => $value['catalognumber'],
                            'status' => 'fail',
                            'message' => 'Failed to save item',
                            'errors' => $errors
                        ];
                        $db->transRollback(); 
                        return $this->response->setJSON([
                            'success' => false,
                            'message' => 'Failed to insert all items. Transaction rolled back.',
                            'results' => $logQuery
                        ]);
                    }
                    
                }

                $db->transCommit();
                return $this->response->setJSON([
                    'success' => true,
                    'message' => 'Processing completed',
                    'results' => $logQuery
                ]);
            }
        }
    }
}