<?php

class LiquidationController {

    /**
     * Create a new liquidation.
     * Uses ALL-TIME earnings — week scoping only applies to the dashboard display.
     */
    public static function create() {
        global $session_user_ID;

        if (!isset($session_user_ID) || empty($session_user_ID)) {
            throw new Exception("User session not found. Please login again.");
        }

        $diagnoArray[0] = 'NO_ERRORS';
        $validate = new Validate();

        $validation = $validate->check($_POST, array(
            'worker_id' => array(
                'name'     => 'Worker',
                'required' => true
            ),
            'liquidation_amount' => array(
                'name'     => 'Liquidation Amount',
                'required' => true,
                'min'      => 1
            ),
            'payment_method' => array(
                'name'     => 'Payment Method',
                'required' => true
            ),
            'liquidation_date' => array(
                'name'     => 'Liquidation Date',
                'required' => true
            )
        ));

        if ($validation->passed()) {
            try {
                $db               = DB::getInstance();
                $liquidationClass = new Liquidation();

                $worker_id          = $_POST['worker_id'];
                $liquidation_amount = $_POST['liquidation_amount'];
                $payment_method     = $_POST['payment_method'];
                $liquidation_date   = $_POST['liquidation_date'];
                $description        = isset($_POST['description']) ? $_POST['description'] : '';

                // Get worker name
                $workerQuery = $db->query(
                    "SELECT firstname, lastname FROM app_users WHERE ID = ?",
                    array($worker_id)
                );
                if (!$workerQuery->count()) {
                    throw new Exception("Worker not found.");
                }
                $worker_data = $workerQuery->first();
                $worker_name = $worker_data->firstname . ' ' . $worker_data->lastname;

                // ALL-TIME earnings (40% of paid entries via WorkerMatrix)
                $matrixClass    = new WorkerMatrix();
                $earnings       = $matrixClass->getWorkerPaidTotal($worker_id);
                $total_earnings = $earnings->grand_total;

                // ALL-TIME deductions
                $already_paid        = $liquidationClass->getTotalLiquidatedForUser($worker_id, 'paid');
                $pending             = $liquidationClass->getPendingLiquidationsForUser($worker_id);
                $expenseClass        = new Expense();
                $liquidated_expenses = $expenseClass->getUserLiquidatedTotal($worker_id);

                $available_amount = $total_earnings - $already_paid - $pending - $liquidated_expenses;

                if ($liquidation_amount > $available_amount) {
                    throw new Exception(
                        "Liquidation amount (" . number_format($liquidation_amount) . " UGX) "
                        . "exceeds available amount (" . number_format($available_amount) . " UGX)"
                    );
                }

                $liquidationClass->insert(array(
                    'user_id'           => $worker_id,
                    'user_name'         => $worker_name,
                    'total_earnings'    => $total_earnings,
                    'amount_liquidated' => $liquidation_amount,
                    'payment_method'    => $payment_method,
                    'liquidation_date'  => $liquidation_date,
                    'description'       => $description,
                    'status'            => 'pending',
                    'created_by'        => $session_user_ID,
                    'created_date'      => date('Y-m-d'),
                    'created_time'      => date('H:i:s')
                ));

                Session::put(
                    'success',
                    'Liquidation created successfully! Amount: '
                    . number_format($liquidation_amount) . ' UGX is pending approval.'
                );

            } catch (Exception $e) {
                $diagnoArray[0] = "ERRORS_FOUND";
                $diagnoArray[]  = $e->getMessage();
            }
        } else {
            return (object) [
                'ERRORS'        => true,
                'ERRORS_SCRIPT' => $validate->getErrorLocation()
            ];
        }

        if ($diagnoArray[0] == 'ERRORS_FOUND') {
            return (object) [
                'ERRORS'        => true,
                'ERRORS_SCRIPT' => $diagnoArray
            ];
        }

        return (object) [
            'ERRORS'        => false,
            'SUCCESS'       => true,
            'ERRORS_SCRIPT' => ""
        ];
    }

    /**
     * Change liquidation status
     */
    public static function changeStatus($status, $liquidation_id) {
        try {
            $liquidationClass = new Liquidation();

            if (!$liquidationClass->find($liquidation_id)) {
                throw new Exception("Liquidation not found");
            }

            $valid_statuses = ['pending', 'paid', 'cancelled'];
            if (!in_array($status, $valid_statuses)) {
                throw new Exception("Invalid status");
            }

            $liquidationClass->update(array(
                'status'       => $status,
                'updated_date' => date('Y-m-d'),
                'updated_time' => date('H:i:s')
            ), $liquidation_id);

            $messages = [
                'paid'      => 'Liquidation marked as PAID! Amount deducted from worker earnings.',
                'cancelled' => 'Liquidation cancelled. Amount returned to available earnings.',
                'pending'   => 'Liquidation status changed to pending.'
            ];

            Session::put('success', $messages[$status]);

            return (object) ['ERRORS' => false, 'SUCCESS' => true];

        } catch (Exception $e) {
            Session::put('errors', $e->getMessage());
            return (object) [
                'ERRORS'        => true,
                'ERRORS_SCRIPT' => $e->getMessage()
            ];
        }
    }

    /**
     * Get all liquidations with optional filters
     */
    public static function getAllLiquidations($filters = array()) {
        try {
            $liquidationClass = new Liquidation();
            return $liquidationClass->getAllLiquidations($filters);
        } catch (Exception $e) {
            return array();
        }
    }

    /**
     * Get worker's available amount for liquidation.
     * Uses ALL-TIME earnings — week scoping only applies to the dashboard display.
     */
    public static function getWorkerAvailableAmount($worker_id) {
        try {
            $matrixClass    = new WorkerMatrix();
            $earnings       = $matrixClass->getWorkerPaidTotal($worker_id);
            $total_earnings = $earnings->grand_total;

            $liquidationClass     = new Liquidation();
            $already_paid         = $liquidationClass->getTotalLiquidatedForUser($worker_id, 'paid');
            $pending_liquidations = $liquidationClass->getPendingLiquidationsForUser($worker_id);

            $expenseClass        = new Expense();
            $liquidated_expenses = $expenseClass->getUserLiquidatedTotal($worker_id);
            $pending_expenses    = $expenseClass->getUserPendingTotal($worker_id);

            $available = $total_earnings
                         - $already_paid
                         - $pending_liquidations
                         - $liquidated_expenses
                         - $pending_expenses;

            return array(
                'total_earnings'       => $total_earnings,
                'already_paid'         => $already_paid,
                'pending_liquidations' => $pending_liquidations,
                'liquidated_expenses'  => $liquidated_expenses,
                'pending_expenses'     => $pending_expenses,
                'available'            => $available
            );

        } catch (Exception $e) {
            return array(
                'total_earnings'       => 0,
                'already_paid'         => 0,
                'pending_liquidations' => 0,
                'liquidated_expenses'  => 0,
                'pending_expenses'     => 0,
                'available'            => 0
            );
        }
    }
}