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

use Google\Cloud\Firestore\FirestoreClient;

class Staffcheckin_model extends CI_Model
{
    private $db_client = null;

    public function __construct()
    {
        parent::__construct();
        $this->load->model('Common');
    }

    /**
     * Get Firestore client instance
     */
    public function get_db()
    {
        if ($this->db_client === null) {
            $keyPath = $this->config->item('firebase_app_key');
            if (file_exists($keyPath)) {
                $keyData = json_decode(file_get_contents($keyPath), true);
                $this->db_client = new FirestoreClient([
                    'projectId' => isset($keyData['project_id']) ? $keyData['project_id'] : 'staff-checkin-b4972',
                    'keyFile' => $keyData
                ]);
            }
        }
        return $this->db_client;
    }

    // ==========================================
    // 1. STORES COLLECTION ("Stores")
    // ==========================================
    public function get_stores($activeOnly = false)
    {
        try {
            $db = $this->get_db();
            if (!$db) return array();
            $col = $db->collection('Stores');
            $docs = $col->documents();
            $list = array();
            foreach ($docs as $doc) {
                if ($doc->exists()) {
                    $d = $doc->data();
                    if ($activeOnly && empty($d['isActive'])) continue;
                    $d['id'] = $doc->id();
                    $list[$doc->id()] = $d;
                }
            }
            return $list;
        } catch (\Throwable $e) {
            log_message('error', 'get_stores error: ' . $e->getMessage());
            return array();
        }
    }

    public function get_store($storeId)
    {
        try {
            $db = $this->get_db();
            if (!$db) return null;
            $doc = $db->collection('Stores')->document($storeId)->snapshot();
            if ($doc->exists()) {
                $d = $doc->data();
                $d['id'] = $doc->id();
                return $d;
            }
            return null;
        } catch (\Throwable $e) {
            return null;
        }
    }

    public function add_store($data)
    {
        try {
            $db = $this->get_db();
            if (!$db) return false;
            $payload = array(
                'name' => isset($data['name']) ? (string)$data['name'] : '',
                'address' => isset($data['address']) ? (string)$data['address'] : '',
                'city' => isset($data['city']) ? (string)$data['city'] : '',
                'country' => isset($data['country']) ? (string)$data['country'] : 'Pakistan',
                'lat' => isset($data['lat']) ? (float)$data['lat'] : 0.0,
                'lng' => isset($data['lng']) ? (float)$data['lng'] : 0.0,
                'isActive' => isset($data['isActive']) ? (bool)$data['isActive'] : true,
                'createdAt' => isset($data['createdAt']) ? (int)$data['createdAt'] : round(microtime(true) * 1000)
            );
            $newDoc = $db->collection('Stores')->newDocument();
            $newDoc->set($payload);
            return $newDoc->id();
        } catch (\Throwable $e) {
            log_message('error', 'add_store error: ' . $e->getMessage());
            return false;
        }
    }

    public function update_store($storeId, $data)
    {
        try {
            $db = $this->get_db();
            if (!$db) return false;
            $updates = array();
            foreach ($data as $k => $v) {
                $updates[] = ['path' => $k, 'value' => $v];
            }
            $db->collection('Stores')->document($storeId)->update($updates);
            return true;
        } catch (\Throwable $e) {
            log_message('error', 'update_store error: ' . $e->getMessage());
            return false;
        }
    }

    public function delete_store($storeId)
    {
        try {
            $db = $this->get_db();
            if (!$db) return false;
            $db->collection('Stores')->document($storeId)->delete();
            return true;
        } catch (\Throwable $e) {
            return false;
        }
    }

    // ==========================================
    // 2. STAFF COLLECTION ("Staff")
    // ==========================================
    public function get_staff($storeId = null)
    {
        try {
            $db = $this->get_db();
            if (!$db) return array();
            $col = $db->collection('Staff');
            if ($storeId) {
                $docs = $col->where('storeId', '=', $storeId)->documents();
            } else {
                $docs = $col->documents();
            }
            $list = array();
            foreach ($docs as $doc) {
                if ($doc->exists()) {
                    $d = $doc->data();
                    $d['id'] = $doc->id();
                    $list[$doc->id()] = $d;
                }
            }
            return $list;
        } catch (\Throwable $e) {
            log_message('error', 'get_staff error: ' . $e->getMessage());
            return array();
        }
    }

    public function get_staff_member($id)
    {
        try {
            $db = $this->get_db();
            if (!$db) return null;
            $doc = $db->collection('Staff')->document($id)->snapshot();
            if ($doc->exists()) {
                $d = $doc->data();
                $d['id'] = $doc->id();
                return $d;
            }
            return null;
        } catch (\Throwable $e) {
            return null;
        }
    }

    public function add_staff($data)
    {
        try {
            $db = $this->get_db();
            if (!$db) return false;
            $payload = array(
                'staffId' => isset($data['staffId']) ? (string)$data['staffId'] : 'ST-' . rand(100, 999),
                'fullName' => isset($data['fullName']) ? (string)$data['fullName'] : '',
                'designation' => isset($data['designation']) ? (string)$data['designation'] : 'Staff',
                'phone' => isset($data['phone']) ? (string)$data['phone'] : '',
                'pinCode' => isset($data['pinCode']) ? (string)$data['pinCode'] : '1234',
                'shift' => isset($data['shift']) ? (string)$data['shift'] : 'Morning',
                'storeId' => isset($data['storeId']) ? (string)$data['storeId'] : '',
                'imageUrl' => isset($data['imageUrl']) ? (string)$data['imageUrl'] : 'https://upload.wikimedia.org/wikipedia/commons/9/9e/Placeholder_Person.jpg',
                'isActive' => isset($data['isActive']) ? (bool)$data['isActive'] : true,
                'createdAt' => isset($data['createdAt']) ? (int)$data['createdAt'] : round(microtime(true) * 1000)
            );
            $newDoc = $db->collection('Staff')->newDocument();
            $newDoc->set($payload);
            return $newDoc->id();
        } catch (\Throwable $e) {
            log_message('error', 'add_staff error: ' . $e->getMessage());
            return false;
        }
    }

    public function update_staff($id, $data)
    {
        try {
            $db = $this->get_db();
            if (!$db) return false;
            $updates = array();
            foreach ($data as $k => $v) {
                $updates[] = ['path' => $k, 'value' => $v];
            }
            $db->collection('Staff')->document($id)->update($updates);
            return true;
        } catch (\Throwable $e) {
            return false;
        }
    }

    public function delete_staff($id)
    {
        try {
            $db = $this->get_db();
            if (!$db) return false;
            $db->collection('Staff')->document($id)->delete();
            return true;
        } catch (\Throwable $e) {
            return false;
        }
    }

    // ==========================================
    // 3. SCHEDULED CHECKIN COLLECTION ("Scheduled_CheckIn")
    // ==========================================
    public function get_schedules()
    {
        try {
            $db = $this->get_db();
            if (!$db) return array();
            $docs = $db->collection('Scheduled_CheckIn')->documents();
            $list = array();
            foreach ($docs as $doc) {
                if ($doc->exists()) {
                    $d = $doc->data();
                    $d['id'] = $doc->id();
                    $list[$doc->id()] = $d;
                }
            }
            return $list;
        } catch (\Throwable $e) {
            log_message('error', 'get_schedules error: ' . $e->getMessage());
            return array();
        }
    }

    public function get_schedule($id)
    {
        try {
            $db = $this->get_db();
            if (!$db) return null;
            $doc = $db->collection('Scheduled_CheckIn')->document($id)->snapshot();
            if ($doc->exists()) {
                $d = $doc->data();
                $d['id'] = $doc->id();
                return $d;
            }
            return null;
        } catch (\Throwable $e) {
            return null;
        }
    }

    public function add_schedule($data)
    {
        try {
            $db = $this->get_db();
            if (!$db) return false;
            $payload = array(
                'title' => isset($data['title']) ? (string)$data['title'] : '',
                'createdAt' => isset($data['createdAt']) ? (int)$data['createdAt'] : round(microtime(true) * 1000),
                'scheduledAt' => isset($data['scheduledAt']) ? (int)$data['scheduledAt'] : round(microtime(true) * 1000),
                'status' => isset($data['status']) ? (string)$data['status'] : 'pending',
                'storeStatus' => isset($data['storeStatus']) && is_array($data['storeStatus']) ? $data['storeStatus'] : array(),
                'tasks' => isset($data['tasks']) && is_array($data['tasks']) ? $data['tasks'] : array()
            );
            $newDoc = $db->collection('Scheduled_CheckIn')->newDocument();
            $newDoc->set($payload);
            return $newDoc->id();
        } catch (\Throwable $e) {
            log_message('error', 'add_schedule error: ' . $e->getMessage());
            return false;
        }
    }

    public function update_schedule($id, $data)
    {
        try {
            $db = $this->get_db();
            if (!$db) return false;
            $updates = array();
            foreach ($data as $k => $v) {
                $updates[] = ['path' => $k, 'value' => $v];
            }
            $db->collection('Scheduled_CheckIn')->document($id)->update($updates);
            return true;
        } catch (\Throwable $e) {
            return false;
        }
    }

    public function delete_schedule($id)
    {
        try {
            $db = $this->get_db();
            if (!$db) return false;
            $db->collection('Scheduled_CheckIn')->document($id)->delete();
            return true;
        } catch (\Throwable $e) {
            return false;
        }
    }

    // ==========================================
    // 4. CHECKIN LOGS COLLECTION ("CheckIn_Logs")
    // ==========================================
    public function get_checkin_logs($limit = 100)
    {
        try {
            $db = $this->get_db();
            if (!$db) return array();
            $docs = $db->collection('CheckIn_Logs')->documents();
            $list = array();
            foreach ($docs as $doc) {
                if ($doc->exists()) {
                    $d = $doc->data();
                    $d['id'] = $doc->id();
                    $list[$doc->id()] = $d;
                }
            }
            // Sort by submittedAt descending
            uasort($list, function ($a, $b) {
                $tA = isset($a['submittedAt']) ? (int)$a['submittedAt'] : 0;
                $tB = isset($b['submittedAt']) ? (int)$b['submittedAt'] : 0;
                return $tB <=> $tA;
            });
            return $list;
        } catch (\Throwable $e) {
            log_message('error', 'get_checkin_logs error: ' . $e->getMessage());
            return array();
        }
    }

    public function get_checkin_log($id)
    {
        try {
            $db = $this->get_db();
            if (!$db) return null;
            $doc = $db->collection('CheckIn_Logs')->document($id)->snapshot();
            if ($doc->exists()) {
                $d = $doc->data();
                $d['id'] = $doc->id();
                return $d;
            }
            return null;
        } catch (\Throwable $e) {
            return null;
        }
    }

    public function get_all_media($type = 'all')
    {
        $logs = $this->get_checkin_logs();
        $mediaList = array();
        foreach ($logs as $logId => $log) {
            if (!empty($log['tasks']) && is_array($log['tasks'])) {
                foreach ($log['tasks'] as $task) {
                    $mType = isset($task['mediaType']) ? strtolower((string)$task['mediaType']) : '';
                    if ($type === 'photo' && !in_array($mType, ['photo', 'image'])) continue;
                    if ($type === 'video' && $mType !== 'video') continue;

                    $mediaList[] = array(
                        'logId' => $logId,
                        'scheduleId' => isset($log['scheduleId']) ? $log['scheduleId'] : '',
                        'staffId' => isset($log['staffId']) ? $log['staffId'] : '',
                        'storeId' => isset($log['storeId']) ? $log['storeId'] : '',
                        'submittedAt' => isset($log['submittedAt']) ? $log['submittedAt'] : 0,
                        'taskName' => isset($task['taskName']) ? $task['taskName'] : '',
                        'mediaType' => $mType,
                        'mediaUrl' => isset($task['mediaUrl']) ? $task['mediaUrl'] : ''
                    );
                }
            }
        }
        return $mediaList;
    }

    // ==========================================
    // 5. USERS COLLECTION ("users")
    // ==========================================
    public function get_users()
    {
        try {
            $db = $this->get_db();
            if (!$db) return array();
            $docs = $db->collection('users')->documents();
            $list = array();
            foreach ($docs as $doc) {
                if ($doc->exists()) {
                    $d = $doc->data();
                    $d['id'] = $doc->id();
                    $list[$doc->id()] = $d;
                }
            }
            return $list;
        } catch (\Throwable $e) {
            return array();
        }
    }

    public function get_user($id)
    {
        try {
            $db = $this->get_db();
            if (!$db) return null;
            $doc = $db->collection('users')->document($id)->snapshot();
            if ($doc->exists()) {
                $d = $doc->data();
                $d['id'] = $doc->id();
                return $d;
            }
            return null;
        } catch (\Throwable $e) {
            return null;
        }
    }

    public function add_user($data)
    {
        try {
            $db = $this->get_db();
            if (!$db) return false;
            $payload = array(
                'email' => isset($data['email']) ? (string)$data['email'] : '',
                'name' => isset($data['name']) ? (string)$data['name'] : '',
                'password' => isset($data['password']) ? (string)$data['password'] : '',
                'userRole' => isset($data['userRole']) ? (string)$data['userRole'] : 'admin',
                'createdAt' => round(microtime(true) * 1000)
            );
            $newDoc = $db->collection('users')->newDocument();
            $newDoc->set($payload);
            return $newDoc->id();
        } catch (\Throwable $e) {
            return false;
        }
    }
}
