<?php
namespace App\Controllers;

use CodeIgniter\API\ResponseTrait;
use CodeIgniter\Controller;
use CodeIgniter\Database\RawSql;

class OrderTestController extends Controller {
    use ResponseTrait;

    public function __construct() {
        $this->db = \Config\Database::connect();
        $this->rulesOrderTest = [
            'NameFirst' => 'required'
        ];
    }

    public function index() {
        $rows = $this->db->table('ordertest')->select("*")->get()->getResultArray();

        if (empty($rows)) {
            return $this->respond([
                'status'  => 'success',
                'message' => "no Data.",
                'data'    => [],
            ], 200);
        }

        return $this->respond([
            'status' => 'success',
            'message'=> "fetch success",
            'data'   => $rows,
        ], 200);
    }

    public function show($OrderID = null) {
        $row=$this->db->table('ordertest')->select("*")->where('OrderID', $OrderID)->get()->getRowArray();
        
        if (empty($row)) {
            return $this->respond([
                'status'  => 'success',
                'message' => "Data not found.",
                'data'    => null,
            ], 200);
        }

        return $this->respond([
            'status' => 'success',
            'message'=> "Data fetched successfully",
            'data'   => $row,
        ], 200);
    }

    public function create() {
        try {
            $input = $this->request->getJSON(true);

            // Prepare data
            $dataOrderTest = $this->prepareOrderTestData($input);
            $dataOrderCom = $this->prepareOrderComData($input);
            $dataOrderAtt = $this->prepareOrderAttData($input);

            if (!$this->validateData($dataLocation, $this->rules)) {
                return $this->failValidationErrors($this->validator->getErrors());
            }

            // Start transaction
            $this->db->transStart();

            // Insert location
            $this->db->table('location')->insert($dataLocation);
            $newLocationID = $this->db->insertID();

            // Insert address if available
            if (!empty($dataLocationAddress)) {
                $dataLocationAddress['LocationID'] = $newLocationID;
                $this->db->table('locationaddress')->insert($dataLocationAddress);
            }

            // Complete transaction
            $this->db->transComplete();

            if ($this->db->transStatus() === false) {
                $dbError = $this->db->error();
                return $this->failServerError(
                    'Failed to create location data (transaction rolled back): ' . ($dbError['message'] ?? 'Unknown database error')
                );
            }

            return $this->respondCreated([
                'status'  => 'success',
                'message' => 'Location created successfully',
                'data'    => $dataLocation,
            ], 201);

        } catch (\Throwable $e) {
            // Ensure rollback if something goes wrong
            if ($this->db->transStatus() !== false) {
                $this->db->transRollback();
            }
            return $this->failServerError('Something went wrong: ' . $e->getMessage());
        }
    }

    public function update() {
        try {
            $input = $this->request->getJSON(true);

            // Prepare data
            $dataLocation = $this->prepareLocationData($input);
            $dataLocationAddress = $this->prepareLocationAddressData($input);

            if (!$this->validateData($dataLocation, $this->rules)) {
                return $this->failValidationErrors( $this->validator->getErrors());
            }

            // Start transaction
            $this->db->transStart();

            // Insert location
            $this->db->table('location')->where('LocationID', $dataLocation["LocationID"])->update($dataLocation);

            // Insert address if available
            if (!empty($dataLocationAddress)) {
                $dataLocationAddress['LocationID'] = $input["LocationID"];
                $this->db->table('locationaddress')->upsert($dataLocationAddress);
            }

            // Complete transaction
            $this->db->transComplete();

            if ($this->db->transStatus() === false) {
                $dbError = $this->db->error();
                return $this->failServerError(
                    'Failed to update location data (transaction rolled back): ' . ($dbError['message'] ?? 'Unknown database error')
                );
            }

            return $this->respondCreated([
                'status'  => 'success',
                'message' => 'Location updated successfully',
                'data'    => $dataLocation,
            ], 201);

        } catch (\Throwable $e) {
            // Ensure rollback if something goes wrong
            if ($this->db->transStatus() !== false) {
                $this->db->transRollback();
            }
            return $this->failServerError('Something went wrong: ' . $e->getMessage());
        }
    }

    public function delete() {
        try {
            $input = $this->request->getJSON(true);
            $LocationID = $input["LocationID"];
            if (!$LocationID) {
                return $this->failValidationError('LocationID is required.');
            }

            
            $location = $this->db->table('location')->where('LocationID', $LocationID)->get()->getRow();
            if (!$location) {
                return $this->failNotFound("LocationID with {$LocationID} not found.");
            }

            $this->db->table('location')->where('LocationID', $LocationID)->update(['DelDate' => NOW()]);

            return $this->respondDeleted([
                'status' => 'success',
                'message' => "Location with {$LocationID} deleted successfully."
            ]);
 
        } catch (\Throwable $e) {
            // Ensure rollback if something goes wrong
            if ($this->db->transStatus() !== false) {
                $this->db->transRollback();
            }
            return $this->failServerError('Something went wrong: ' . $e->getMessage());
        }
    }

    private function prepareLocationData(array $input): array {
        $LinkTo = null;
        if (!empty($input['LinkTo'])) {
            $ids = array_column($input['LinkTo'], 'InternalPID');
            $LinkTo = implode(',', $ids);
        }

        $data = [
            "LocCode" => $input['LocCode'] ?? null,
            "Parent" => $input['Parent'] ?? null,
            "LocFull" => $input['LocFull'] ?? null,
            "Description" => $input['Description'] ?? null,
        ];

        if(!empty($input["LocationID"])) { $data["LocationID"] = $input["LocationID"]; }

        return $data;
    }

    private function prepareLocationAddressData(array $input): array {
        $data = [
            "LocationID" => $input['LocationID'] ?? null,
            "Street1" => $input['Street1'] ?? null,
            "Street2" => $input['Street2'] ?? null,
            "City" => $input['City'] ?? null,
            "Province" => $input['Province'] ?? null,
            "PostCode" => $input['PostCode'] ?? null,
            "GeoLocationSystem" => $input['GeoLocationSystem'] ?? null,
            "GeoLocationData" => $input['GeoLocationData'] ?? null,
        ];
        
        return $data;
    }
}
