<?php defined('BASEPATH') OR exit('No direct script access allowed');

class History {

    protected $CI;
    private $fieldMap = [
    // Category/lookup fields
    'stages'        => ['type' => 'category', 'col' => 'stages'],
    'lead_priority' => ['type' => 'category', 'col' => 'lead_priority'],
    'lead_source'   => ['type' => 'category', 'col' => 'lead_source'],
    'enquiry_for'   => ['type' => 'category', 'col' => 'enquiry_for'],

    // Assignee
    'assignee'      => ['type' => 'admin', 'col' => 'assignee'],

    // Text fields
    'name'          => ['type' => 'text'],
    'email'         => ['type' => 'text'],
    'address'       => ['type' => 'text'],
    'remark'        => ['type' => 'text'],
    'billing_name'  => ['type' => 'text'],
    'billing_address' => ['type' => 'text'],
    'gst_no'  => ['type' => 'text'],
    'gst_state'  => ['type' => 'text'],
    'adhar_number'  => ['type' => 'text'],
    'preferred_communication'  => ['type' => 'text'],
    'contact_type'  => ['type' => 'text'],
    'customer_portal_access'  => ['type' => 'text'],
    


    // Date fields
    'follow_up_date' => ['type' => 'date'],

    // Conversion
    'type'           => ['type' => 'text', 'col' => 'type'],
];

    public function __construct() {
        $this->CI =& get_instance();
    }

    /**
     * Add history entry
     *
     * @param string $record_type   (lead, customer, task, appointment, ticket)
     * @param int    $record_id
     * @param string $col           (field name: stage, priority, assignee)
     * @param mixed  $old_val
     * @param mixed  $new_val
     * @param int    $parent_record_id (e.g., lead parent is the customer)
     * @param int    $user_id
     * @param string $description
     */
    public function add($record_type, $record_id, $col, $old_val, $new_val, $parent_record_id = null, $user_id = null, $description = null)
    {
        // No change → no history
        if ($old_val == $new_val) return;

        // Auto detect description if not provided
        if (!$description) {
            $description = $this->generateDescription($col, $old_val, $new_val);
        }

        // Map snapshot values
        $snapshot = $this->resolveSnapshot($col, $old_val, $new_val);

        $data = [
            'record_id'        => $record_id,
            'record_type'      => $record_type,
            'parent_record_id' => $parent_record_id ?? $record_id,
            'col'              => $col,
            'old_val'          => $old_val,
            'new_val'          => $new_val,
            'old_desc'         => $snapshot['old_desc'],
            'new_desc'         => $snapshot['new_desc'],
            'description'      => $description,
            'user_id'          => $user_id ?? $this->currentUser(),
            'activity_date'    => date("Y-m-d H:i:s"),
        ];

        $this->CI->db->insert('history', $data);
    }
    private function getControllerJoinMap()
    {
        $columnNames = property_exists($this->CI, 'columnNames') ? $this->CI->columnNames : [];
        $customCol   = property_exists($this->CI, 'customCol') ? $this->CI->customCol : [];

        return array_merge($columnNames, $customCol);
    }

    /**
     * Resolve snapshot display text for categories, admin, text fields
     */
    // private function resolveSnapshot($col, $old_val, $new_val)
    // {
    //     $old_desc = null;
    //     $new_desc = null;

    //     // CATEGORY LOOKUP FIELDS
    //     $categoryCols = ['stage', 'priority', 'source', 'lead_priority', 'lead_source', 'stages','enquiry_for'];

    //     if (in_array($col, $categoryCols)) {
    //         $old_desc = $this->categoryName($old_val);
    //         $new_desc = $this->categoryName($new_val);
    //     }

    //     // ASSIGNEE LOOKUP FIELD
    //     if ($col === 'assignee') {
    //         $old_desc = $this->adminName($old_val);
    //         $new_desc = $this->adminName($new_val);
    //     }

    //     // TEXT FIELDS
    //     $textFields = ['name','email','address','remark','company_name','billing_address'];
    //     if (in_array($col, $textFields)) {
    //         $old_desc = $old_val;
    //         $new_desc = $new_val;
    //     }

    //     // FOLLOW UP DATE
    //     if ($col === 'follow_up_date') {
    //         $old_desc = $old_val;
    //         $new_desc = $new_val;
    //     }

    //     return [
    //         'old_desc' => $old_desc,
    //         'new_desc' => $new_desc
    //     ];
    // }
    private function resolveSnapshot($col, $old_val, $new_val)
    {
        $map = $this->getControllerJoinMap();

        $old_desc = null;
        $new_desc = null;

        // If field exists in controller join mapping
        if (isset($map[$col])) {

            $m = $map[$col];

            // Admin lookup (admin table)
            if ($m['table'] === 'admin') {
                $old_desc = $this->adminName($old_val);
                $new_desc = $this->adminName($new_val);
            }

            // Category lookup
            else if ($m['table'] === 'categories') {
                $old_desc = $this->categoryName($old_val);
                $new_desc = $this->categoryName($new_val);
            }

            // Other lookup tables
            else {
                $old_desc = $this->genericLookup($m, $old_val);
                $new_desc = $this->genericLookup($m, $new_val);
            }
        }
        else {
            // Fallback for text fields
            $old_desc = $old_val;
            $new_desc = $new_val;
        }

        return [
            'old_desc' => $old_desc,
            'new_desc' => $new_desc
        ];
    }



    /**
     * Get Admin Name
     */
    private function adminName($id)
    {
        if (!$id) return null;
        $q = $this->CI->db->select('name')->from('admin')->where('adminID', $id)->get();
        return $q->num_rows() ? $q->row()->name : null;
    }

    /**
     * Get Category Name
     */
    private function categoryName($id)
    {
        if (!$id) return null;
        $q = $this->CI->db->select('categoryName')->from('categories')->where('category_id', $id)->get();
        return $q->num_rows() ? $q->row()->categoryName : null;
    }

    /**
     * Auto-generate description if not provided
     */
    private function generateDescription($col, $old_val, $new_val)
    {
        if ($old_val === null || $old_val === '') {
            return ucfirst($col) . " set";
        }
        if ($new_val === null || $new_val === '') {
            return ucfirst($col) . " removed";
        }
        return ucfirst($col) . " changed";
    }

    /**
     * Helper for current logged-in user
     */
    private function currentUser()
    {
        return $this->CI->session->userdata('adminID') ?? null;
    }
    public function compareAndAdd($record_type, $record_id, $old, $new, $parent_record_type = null,$parent_record_id = null, $user_id = null)
    {
        // Convert objects to arrays
        if (is_object($old)) $old = (array) $old;
        if (is_object($new)) $new = (array) $new;

        // If old/new are arrays of objects (example: CI get result array)
        if (isset($old) && is_object($old)) $old = (array) $old;
        if (isset($new) && is_object($new)) $new = (array) $new;

        foreach ($new as $field => $new_val) {

            if ($field === "modified_date" || $field === "modified_by") continue;
            // Skip fields not present in old
            if (!array_key_exists($field, $old)) continue;

            $old_val = $old[$field];

            // Skip unchanged
            if ($old_val == $new_val) continue;

           $controllerMap = $this->getControllerJoinMap();

            // Use controller join column if exists
            $colName = isset($controllerMap[$field])
                ? ($controllerMap[$field]['col'] ?? $field)
                : $field;

            $description = $this->generateDescription($colName, $old_val, $new_val);
            $snapshot    = $this->resolveSnapshot($colName, $old_val, $new_val);

            $data = [
                'record_id'        => $record_id,
                'record_type'      => $record_type,
                'parent_record_id' => $parent_record_id ?? $record_id,
                'parent_record_type'=> $parent_record_type,
                'col'              => $colName,
                'old_val'          => $old_val,
                'new_val'          => $new_val,
                'old_desc'         => $snapshot['old_desc'],
                'new_desc'         => $snapshot['new_desc'],
                'description'      => $description,
                'user_id'          => $user_id ?? $this->currentUser(),
                'activity_date'    => date("Y-m-d H:i:s"),
            ];

            $this->CI->db->insert('history', $data);
        }
    }

    // private function resolveSnapshot($col, $old_val, $new_val)
    // {
    //     $old_desc = null;
    //     $new_desc = null;

    //     // if category
    //     if (in_array($col, ['stage','priority','source'])) {
    //         $old_desc = $this->categoryName($old_val);
    //         $new_desc = $this->categoryName($new_val);
    //     }

    //     // if admin
    //     if ($col === 'assignee') {
    //         $old_desc = $this->adminName($old_val);
    //         $new_desc = $this->adminName($new_val);
    //     }

    //     // regular text
    //     if (!in_array($col, ['stage','priority','source','assignee']) ) {
    //         $old_desc = $old_val;
    //         $new_desc = $new_val;
    //     }

    //     return [
    //         'old_desc' => $old_desc,
    //         'new_desc' => $new_desc
    //     ];
    // }
    public function addCreate($record_type, $record_id, $parent_record_id = null,$parent_record_type=null, $user_id = null)
    {
        $this->CI->db->insert('history', [
            'record_id'        => $record_id,
            'record_type'      => $record_type,
            'parent_record_id' => $parent_record_id ?? $record_id,
            'parent_record_type'=> $parent_record_type,
            'col'              => $record_type,
            'description'      => ucfirst($record_type) . ' Created',
            'action_type'      => 'created',
            'user_id'          => $user_id ?? $this->currentUser(),
            'activity_date'    => date("Y-m-d H:i:s")
        ]);
    }
    private function genericLookup($m, $id)
    {
        if (!$id) return null;

        $q = $this->CI->db
            ->select($m['column'])
            ->from($m['table'])
            ->where($m['key2'], $id)
            ->get();

        return $q->num_rows() ? $q->row()->{$m['column']} : null;
    }
    /**
     * Add a single history entry (no comparison needed)
     *
     * @param string $record_type  (note, email, call, ticket, appointment)
     * @param int    $record_id
     * @param string $col          Field name
     * @param mixed  $old_val
     * @param mixed  $new_val
     * @param string $parent_record_type  (lead, customer, task)
     * @param string|null $description
     * @param int|null $parent_record_id
     * @param int|null $user_id
     */
    public function addEntry($record_type, $record_id, $col, $old_val, $new_val, $description = null, $parent_record_type=null,$parent_record_id = null, $user_id = null)
    {
        // Auto-generate description if not provided
        if (!$description) {
            if ($old_val === null || $old_val === '') {
                $description = ucfirst($col) . ' set';
            } elseif ($new_val === null || $new_val === '') {
                $description = ucfirst($col) . ' removed';
            } else {
                $description = ucfirst($col) . ' changed';
            }
        }

        // Resolve snapshot description (names, category label, admin name, etc.)
        $snapshot = $this->resolveSnapshot($col, $old_val, $new_val);

        $data = [
            'record_id'        => $record_id,
            'record_type'      => $record_type,
            'parent_record_id' => $parent_record_id ?? $record_id,
            'parent_record_type'=> $parent_record_type,
            'col'              => $col,
            'old_val'          => $old_val,
            'new_val'          => $new_val,
            'old_desc'         => $snapshot['old_desc'],
            'new_desc'         => $snapshot['new_desc'],
            'description'      => $description,
            'user_id'          => $user_id ?? $this->currentUser(),
            'activity_date'    => date("Y-m-d H:i:s")
        ];

        $this->CI->db->insert('history', $data);
    }



}
