<?php
require_once 'Logger.php';
require_once 'Notifications.php';

class Deposit {
    private $conn;
    private $logger;
    private $notifications;

    public function __construct($db, $logger = null) {
        $this->conn = $db;
        $this->logger = $logger;
        $this->notifications = new Notifications($db, $logger);
    }

    public function addDeposit($branchId, $depositDate, $amount, $notes = '', $userId = null) {
        try {
            $stmt = $this->conn->prepare("
                INSERT INTO deposits (branch_id, deposit_date, amount, notes, created_by)
                VALUES (:branch_id, :deposit_date, :amount, :notes, :created_by)
            ");

            $stmt->bindParam(':branch_id', $branchId, PDO::PARAM_INT);
            $stmt->bindParam(':deposit_date', $depositDate);
            $stmt->bindParam(':amount', $amount);
            $stmt->bindParam(':notes', $notes);
            $stmt->bindParam(':created_by', $userId, PDO::PARAM_INT);

            error_log("SQL: " . $stmt->queryString);
            error_log("Params: branch_id=$branchId, deposit_date=$depositDate, amount=$amount, notes=$notes, created_by=$userId");

            $result = $stmt->execute();
            $depositId = $result ? $this->conn->lastInsertId() : null;

            if ($result && $this->logger) {
                $depositData = [
                    'branch_id' => $branchId,
                    'deposit_date' => $depositDate,
                    'amount' => $amount,
                    'notes' => $notes,
                    'created_by' => $userId
                ];
                $this->logger->logDeposit('CREATE', $depositId, $depositData);
            }

            if ($result) {
                $message = "Deposit ".$depositId." for branch ".$branchId." has been recorded.";
                $this->notifications->createNotification($branchId, $message, 'Admin');
            }

            return $result ? $depositId : false;
        } catch (PDOException $e) {
            error_log("Error adding deposit: " . $e->getMessage());
            return false;
        }
    }

    public function getDepositsForWeek($branchId, $startDate, $endDate, $adminView = false, $reportId = null) {
        try {
            $sql = "
                SELECT
                    d.id as deposit_id,
                    d.deposit_date,
                    d.amount,
                    d.notes,
                    d.created_at,
                    u.username as created_by_user
                FROM
                    deposits d
                LEFT JOIN
                    users u ON d.created_by = u.user_id
                WHERE
                    d.branch_id = :branch_id";

            if ($adminView && $reportId !== null) {
                $sql .= " AND d.notes LIKE :report_note";
            } else {
                $sql .= " AND (d.notes IS NULL OR d.notes NOT LIKE '%[Verified in Report #%')";
            }

            $sql .= " ORDER BY d.deposit_date ASC";

            $stmt = $this->conn->prepare($sql);
            $stmt->bindParam(':branch_id', $branchId, PDO::PARAM_INT);

            if ($adminView && $reportId !== null) {
                $reportNote = '%[Verified in Report #' . $reportId . ']%';
                $stmt->bindParam(':report_note', $reportNote, PDO::PARAM_STR);
            }

            $stmt->execute();
            return $stmt->fetchAll(PDO::FETCH_ASSOC);
        } catch (PDOException $e) {
            error_log("Error getting deposits for week/report: " . $e->getMessage());
            return [];
        }
    }


	public function getDepositsForEdit($branchId, $startDate, $endDate, $adminView = false, $reportId = null) {
        try {
            $sql = "
                SELECT
                    d.id as deposit_id,
                    d.deposit_date,
                    d.amount,
                    d.notes,
                    d.created_at,
                    u.username as created_by_user
                FROM
                    deposits d
                LEFT JOIN
                    users u ON d.created_by = u.user_id
                WHERE
                    d.branch_id = :branch_id";

            if ($adminView && $reportId !== null) {
                $sql .= " AND d.notes LIKE :report_note";
            } else {
                $sql .= " AND (d.notes IS NULL OR d.notes NOT LIKE '%[Verified in Report #%')";
            }

            $sql .= " ORDER BY d.deposit_date ASC";

            $stmt = $this->conn->prepare($sql);
            $stmt->bindParam(':branch_id', $branchId, PDO::PARAM_INT);

            if ($adminView && $reportId !== null) {
                $reportNote = '%[Verified in Report #' . $reportId . ']%';
                $stmt->bindParam(':report_note', $reportNote, PDO::PARAM_STR);
            }

            $stmt->execute();
            return $stmt->fetchAll(PDO::FETCH_ASSOC);
        } catch (PDOException $e) {
            error_log("Error getting deposits for week/report: " . $e->getMessage());
            return [];
        }
    }


    public function getTotalDeposits($branchId, $startDate, $endDate, $adminView = false, $reportId = null) {
        try {
            $sql = "
                SELECT SUM(amount) as total
                FROM deposits
                WHERE branch_id = :branch_id";

            if ($adminView && $reportId !== null) {
                $sql .= " AND notes LIKE :report_note";
            } else {
                $sql .= " AND (notes IS NULL OR notes NOT LIKE '%[Verified in Report #%')";
            }

            $stmt = $this->conn->prepare($sql);
            $stmt->bindParam(':branch_id', $branchId, PDO::PARAM_INT);

            if ($adminView && $reportId !== null) {
                $reportNote = '%[Verified in Report #' . $reportId . ']%';
                $stmt->bindParam(':report_note', $reportNote, PDO::PARAM_STR);
            }

            $stmt->execute();

            $result = $stmt->fetch(PDO::FETCH_ASSOC);
            return $result['total'] ?? 0;
        } catch (PDOException $e) {
            error_log("Error getting total deposits for week/report: " . $e->getMessage());
            return 0;
        }
    }

    public function updateDeposit($depositId, $depositDate, $amount, $notes) {
        try {
            $oldData = null;
            if ($this->logger) {
                $oldDeposit = $this->getDepositById($depositId);
                if ($oldDeposit) {
                    $oldData = [
                        'deposit_date' => $oldDeposit['deposit_date'],
                        'amount' => $oldDeposit['amount'],
                        'notes' => $oldDeposit['notes']
                    ];
                }
            }

            $stmt = $this->conn->prepare("
                UPDATE deposits
                SET deposit_date = :deposit_date,
                    amount = :amount,
                    notes = :notes,
                    updated_at = NOW()
                WHERE id = :deposit_id
            ");

            $stmt->bindParam(':deposit_id', $depositId, PDO::PARAM_INT);
            $stmt->bindParam(':deposit_date', $depositDate);
            $stmt->bindParam(':amount', $amount);
            $stmt->bindParam(':notes', $notes);

            $result = $stmt->execute();

            if ($result && $this->logger && $oldData) {
                $newData = [
                    'deposit_date' => $depositDate,
                    'amount' => $amount,
                    'notes' => $notes
                ];
                $this->logger->logDeposit('UPDATE', $depositId, $newData, $oldData);
            }

            return $result;
        } catch (PDOException $e) {
            error_log("Error updating deposit: " . $e->getMessage());
            return false;
        }
    }

    public function deleteDeposit($depositId) {
        try {
            $depositData = null;
            if ($this->logger) {
                $depositData = $this->getDepositById($depositId);
            }

            $stmt = $this->conn->prepare("
                DELETE FROM deposits
                WHERE id = :deposit_id
            ");

            $stmt->bindParam(':deposit_id', $depositId, PDO::PARAM_INT);

            $result = $stmt->execute();

            if ($result && $this->logger && $depositData) {
                $this->logger->logDeposit('DELETE', $depositId, null, $depositData);
            }

            return $result;
        } catch (PDOException $e) {
            error_log("Error deleting deposit: " . $e->getMessage());
            return false;
        }
    }

    public function getDepositById($depositId) {
        try {
            $stmt = $this->conn->prepare("
                SELECT
                    d.id,
                    d.branch_id,
                    d.report_id,
                    d.deposit_date,
                    d.amount,
                    d.created_at,
                    d.notes,
                    d.created_by,
                    b.branch_name,
                    u.username as created_by_user
                FROM deposits d
                LEFT JOIN branches b ON d.branch_id = b.branch_id
                LEFT JOIN users u ON d.created_by = u.user_id
                WHERE d.id = :deposit_id
            ");
            $stmt->bindParam(':deposit_id', $depositId, PDO::PARAM_INT);
            $stmt->execute();
            return $stmt->fetch(PDO::FETCH_ASSOC) ?: null;
        } catch (PDOException $e) {
            error_log("Error getting deposit by ID: " . $e->getMessage());
            return null;
        }
    }

    public function isDepositUnverified($depositId) {
        try {
            $stmt = $this->conn->prepare("
                SELECT notes
                FROM deposits
                WHERE id = :deposit_id
            ");
            $stmt->bindParam(':deposit_id', $depositId, PDO::PARAM_INT);
            $stmt->execute();
            $result = $stmt->fetch(PDO::FETCH_ASSOC);
            if (!$result) {
                return false;
            }
            return empty($result['notes']) || strpos($result['notes'], '[Verified in Report #') === false;
        } catch (PDOException $e) {
            error_log("Error checking deposit verification: " . $e->getMessage());
            return false;
        }
    }
}
?>
