<?php
/**
 * Sale.php - Vehicle Sale Management Class
 * Manages vehicle sales records and document requirements
 */

class Sale {
    private $pdo;
    private $document;

    public function __construct($pdo, $document = null) {
        $this->pdo = $pdo;
        $this->document = $document;
    }

    /**
     * Create new sale
     */
    public function create($user_id, $customer_id, $vehicle_registration, $vehicle_make, $vehicle_model, $vehicle_year, $vehicle_colour, $vehicle_vin, $sale_type = 'direct_sale', $sale_price = null, $notes = null) {
        try {
            $stmt = $this->pdo->prepare("
                INSERT INTO sales (user_id, customer_id, vehicle_registration, vehicle_make, vehicle_model, vehicle_year, vehicle_colour, vehicle_vin, sale_type, sale_price, notes, created_ip)
                VALUES (:user_id, :customer_id, :vehicle_registration, :vehicle_make, :vehicle_model, :vehicle_year, :vehicle_colour, :vehicle_vin, :sale_type, :sale_price, :notes, :created_ip)
            ");

            $stmt->execute([
                ':user_id' => $user_id,
                ':customer_id' => $customer_id,
                ':vehicle_registration' => sanitize_input($vehicle_registration),
                ':vehicle_make' => sanitize_input($vehicle_make),
                ':vehicle_model' => sanitize_input($vehicle_model),
                ':vehicle_year' => intval($vehicle_year),
                ':vehicle_colour' => sanitize_input($vehicle_colour),
                ':vehicle_vin' => sanitize_input($vehicle_vin),
                ':sale_type' => $sale_type,
                ':sale_price' => floatval($sale_price),
                ':notes' => sanitize_input($notes),
                ':created_ip' => get_client_ip()
            ]);

            $sale_id = $this->pdo->lastInsertId();
            log_action($user_id, null, 'SALE_CREATED', "Sale created for customer $customer_id - Registration: $vehicle_registration");

            return $sale_id;
        } catch (Exception $e) {
            log_action($user_id, null, 'SALE_CREATE_ERROR', 'Error: ' . $e->getMessage());
            return false;
        }
    }

    /**
     * Get sale by ID
     */
    public function get($sale_id, $user_id = null) {
        try {
            $query = "SELECT * FROM sales WHERE id = :id";
            $params = [':id' => $sale_id];

            if ($user_id) {
                $query .= " AND user_id = :user_id";
                $params[':user_id'] = $user_id;
            }

            $stmt = $this->pdo->prepare($query);
            $stmt->execute($params);
            return $stmt->fetch(PDO::FETCH_ASSOC);
        } catch (Exception $e) {
            return false;
        }
    }

    /**
     * Get all sales for a user
     */
    public function getByUser($user_id, $status = null, $limit = 50, $offset = 0) {
        try {
            $query = "SELECT s.*, c.first_name, c.last_name, c.email FROM sales s
                     LEFT JOIN customers c ON s.customer_id = c.id
                     WHERE s.user_id = :user_id";
            $params = [':user_id' => $user_id];

            if ($status) {
                $query .= " AND s.sale_status = :status";
                $params[':status'] = $status;
            }

            $query .= " ORDER BY s.created_at DESC LIMIT :limit OFFSET :offset";

            $stmt = $this->pdo->prepare($query);
            $stmt->bindValue(':user_id', $user_id, PDO::PARAM_INT);
            if ($status) {
                $stmt->bindValue(':status', $status, PDO::PARAM_STR);
            }
            $stmt->bindValue(':limit', $limit, PDO::PARAM_INT);
            $stmt->bindValue(':offset', $offset, PDO::PARAM_INT);
            $stmt->execute();

            return $stmt->fetchAll(PDO::FETCH_ASSOC);
        } catch (Exception $e) {
            return [];
        }
    }

    /**
     * Get sale status with document completion
     */
    public function getSaleStatus($sale_id) {
        try {
            $sale = $this->get($sale_id);
            if (!$sale) return null;

            // Get all required documents
            $stmt = $this->pdo->prepare("
                SELECT sd.*, d.status as document_status
                FROM sale_documents sd
                LEFT JOIN documents d ON sd.document_id = d.id
                WHERE sd.sale_id = :sale_id AND sd.is_required = TRUE
                ORDER BY sd.sequence_number
            ");
            $stmt->execute([':sale_id' => $sale_id]);
            $documents = $stmt->fetchAll(PDO::FETCH_ASSOC);

            // Calculate completion percentage
            $total = count($documents);
            $signed = 0;

            foreach ($documents as $doc) {
                if ($doc['signed_status'] === 'signed' || $doc['document_status'] === 'signed') {
                    $signed++;
                }
            }

            $completion = $total > 0 ? round(($signed / $total) * 100) : 0;

            return [
                'sale' => $sale,
                'documents' => $documents,
                'total_required' => $total,
                'signed' => $signed,
                'pending' => $total - $signed,
                'completion_percentage' => $completion,
                'is_complete' => ($signed === $total) && $total > 0
            ];
        } catch (Exception $e) {
            return null;
        }
    }

    /**
     * Add document to sale
     */
    public function addDocument($sale_id, $document_id, $document_type, $sequence_number = null, $is_required = true) {
        try {
            if (!$sequence_number) {
                $stmt = $this->pdo->prepare("SELECT MAX(sequence_number) as max_seq FROM sale_documents WHERE sale_id = :sale_id");
                $stmt->execute([':sale_id' => $sale_id]);
                $result = $stmt->fetch(PDO::FETCH_ASSOC);
                $sequence_number = ($result['max_seq'] ?? 0) + 1;
            }

            $stmt = $this->pdo->prepare("
                INSERT INTO sale_documents (sale_id, document_id, document_type, sequence_number, is_required)
                VALUES (:sale_id, :document_id, :document_type, :sequence_number, :is_required)
            ");

            return $stmt->execute([
                ':sale_id' => $sale_id,
                ':document_id' => $document_id,
                ':document_type' => $document_type,
                ':sequence_number' => $sequence_number,
                ':is_required' => $is_required ? 1 : 0
            ]);
        } catch (Exception $e) {
            return false;
        }
    }

    /**
     * Mark document as signed in sale
     */
    public function markDocumentSigned($sale_id, $document_id) {
        try {
            $stmt = $this->pdo->prepare("
                UPDATE sale_documents
                SET signed_status = 'signed', signed_at = CURRENT_TIMESTAMP
                WHERE sale_id = :sale_id AND document_id = :document_id
            ");

            $result = $stmt->execute([
                ':sale_id' => $sale_id,
                ':document_id' => $document_id
            ]);

            // Check if sale is now complete
            if ($result) {
                $status = $this->getSaleStatus($sale_id);
                if ($status['is_complete']) {
                    $this->updateStatus($sale_id, 'complete');
                    log_action(null, null, 'SALE_COMPLETED', "All documents signed for sale $sale_id");
                }
            }

            return $result;
        } catch (Exception $e) {
            return false;
        }
    }

    /**
     * Update sale status
     */
    public function updateStatus($sale_id, $status) {
        try {
            $valid_statuses = ['draft', 'pending_signatures', 'complete', 'archived', 'disputed'];
            if (!in_array($status, $valid_statuses)) {
                return false;
            }

            $completed_at = ($status === 'complete') ? 'CURRENT_TIMESTAMP' : 'NULL';

            $stmt = $this->pdo->prepare("
                UPDATE sales
                SET sale_status = :status, completed_at = IF(:status = 'complete', CURRENT_TIMESTAMP, completed_at)
                WHERE id = :sale_id
            ");

            return $stmt->execute([
                ':sale_id' => $sale_id,
                ':status' => $status
            ]);
        } catch (Exception $e) {
            return false;
        }
    }

    /**
     * Get incomplete sales (for reporting)
     */
    public function getIncomplete($user_id, $limit = 20) {
        try {
            $stmt = $this->pdo->prepare("
                SELECT s.*, c.first_name, c.last_name, c.email,
                       COUNT(sd.id) as total_docs,
                       SUM(CASE WHEN sd.signed_status = 'signed' THEN 1 ELSE 0 END) as signed_docs
                FROM sales s
                LEFT JOIN customers c ON s.customer_id = c.id
                LEFT JOIN sale_documents sd ON s.id = sd.sale_id
                WHERE s.user_id = :user_id AND s.sale_status IN ('draft', 'pending_signatures')
                GROUP BY s.id
                ORDER BY s.created_at DESC
                LIMIT :limit
            ");

            $stmt->bindValue(':user_id', $user_id, PDO::PARAM_INT);
            $stmt->bindValue(':limit', $limit, PDO::PARAM_INT);
            $stmt->execute();

            return $stmt->fetchAll(PDO::FETCH_ASSOC);
        } catch (Exception $e) {
            return [];
        }
    }

    /**
     * Get sales statistics
     */
    public function getStats($user_id) {
        try {
            $stmt = $this->pdo->prepare("
                SELECT
                    COUNT(*) as total,
                    SUM(CASE WHEN sale_status = 'complete' THEN 1 ELSE 0 END) as completed,
                    SUM(CASE WHEN sale_status = 'pending_signatures' THEN 1 ELSE 0 END) as pending,
                    SUM(CASE WHEN sale_status = 'draft' THEN 1 ELSE 0 END) as draft,
                    SUM(CASE WHEN sale_status = 'disputed' THEN 1 ELSE 0 END) as disputed,
                    AVG(CAST(DATEDIFF(completed_at, created_at) as DECIMAL)) as avg_days_to_complete
                FROM sales
                WHERE user_id = :user_id
            ");

            $stmt->execute([':user_id' => $user_id]);
            return $stmt->fetch(PDO::FETCH_ASSOC);
        } catch (Exception $e) {
            return null;
        }
    }
}
?>
