<?php
/**
  * Ahead WebSoft Technologies Pvt Ltd.
  * @copyright  Copyright 2006-2026 Ahead WebSoft Technologies Pvt Ltd.
  * @license    https://www.socialengine.com/policies
*/

class Core_SavecollectionController extends Core_Controller_Action_Standard
{
  public function init()
  {
    // List of AJAX actions that return JSON (not HTML pages)
    $ajaxActions = array('save', 'unsave', 'is-saved', 'saved-items', 'collection-create',
      'collection-edit', 'collection-delete', 'add-to-collections', 'remove-from-collection',
      'collections-for-item', 'collection-items', 'get-collections-sheet');
    
    $action = $this->getRequest()->getActionName();
    $isAjax = in_array($action, $ajaxActions);

    // Require authentication
    if (!$this->_helper->requireUser()->isValid()) {
      if ($isAjax) {
        echo json_encode(array('error' => '1', 'error_message' => 'not_authenticated', 'result' => ''));
        die;
      }
      return;
    }

    // Check feature toggle
    if (!Engine_Api::_()->getApi('savecollection', 'core')->isEnabled()) {
      if ($isAjax) {
        echo json_encode(array('error' => '1', 'error_message' => 'feature_disabled', 'result' => ''));
        die;
      }
      return $this->_helper->redirector->gotoRoute(array(), 'default', true);
    }
  }

  public function indexAction()
  {
    // Get params for filtering/sorting
    $page = $this->_getParam('page', 1);
    $limit = $this->_getParam('limit', 20);
    $search = $this->_getParam('search', '');
    $sort = $this->_getParam('sort', 'date_newest');
    $contentType = $this->_getParam('content_type', '');

    $viewer = Engine_Api::_()->user()->getViewer();
    $api = Engine_Api::_()->getApi('savecollection', 'core');

    $params = array(
      'page' => $page,
      'limit' => $limit,
      'search' => $search,
      'sort' => $sort,
      'content_type' => $contentType,
    );

    $paginator = $api->getSavedItems($viewer, $params);

    $this->view->paginator = $paginator;
    $this->view->search = $search;
    $this->view->sort = $sort;
    $this->view->contentType = $contentType;
    $this->view->supportedTypes = $api->getSupportedContentTypes();
  }

  public function collectionsAction()
  {
    $page = $this->_getParam('page', 1);
    $limit = $this->_getParam('limit', 20);
    $search = $this->_getParam('search', '');

    $viewer = Engine_Api::_()->user()->getViewer();
    $api = Engine_Api::_()->getApi('savecollection', 'core');

    $params = array(
      'page' => $page,
      'limit' => $limit,
      'search' => $search,
    );

    $paginator = $api->getCollections($viewer, $params);

    $this->view->paginator = $paginator;
    $this->view->search = $search;
  }

  public function detailAction()
  {
    $collectionId = (int) $this->_getParam('collection_id', 0);

    if (!$collectionId) {
      return $this->_helper->redirector->gotoRoute(array('module' => 'core', 'controller' => 'savecollection', 'action' => 'collections'), 'default', true);
    }

    $viewer = Engine_Api::_()->user()->getViewer();
    $collectionsTable = Engine_Api::_()->getDbtable('collections', 'core');
    $collection = $collectionsTable->find($collectionId)->current();

    // Validate collection exists and belongs to viewer
    if (!$collection || $collection->user_id != $viewer->getIdentity()) {
      return $this->_helper->redirector->gotoRoute(array('module' => 'core', 'controller' => 'savecollection', 'action' => 'collections'), 'default', true);
    }

    $api = Engine_Api::_()->getApi('savecollection', 'core');

    $page = $this->_getParam('page', 1);
    $limit = $this->_getParam('limit', 20);
    $search = $this->_getParam('search', '');
    $sort = $this->_getParam('sort', 'date_newest');
    $contentType = $this->_getParam('content_type', '');

    $params = array(
      'page' => $page,
      'limit' => $limit,
      'search' => $search,
      'sort' => $sort,
      'content_type' => $contentType,
    );

    $paginator = $api->getCollectionItems($collection, $params);

    $this->view->collection = $collection;
    $this->view->paginator = $paginator;
    $this->view->search = $search;
    $this->view->sort = $sort;
    $this->view->contentType = $contentType;
    $this->view->supportedTypes = $api->getSupportedContentTypes();
  }

   /**
   * POST - Save a content item for the authenticated viewer.
   * Params: content_type, content_id
   */
  public function saveAction()
  {
    $contentType = $this->_getParam('content_type', '');
    $contentId = $this->_getParam('content_id', 0);

    // Validate content_type is not empty
    if (empty($contentType)) {
       echo json_encode(array(
        'error' => '1',
        'error_message' => 'invalid_content_type',
        'result' => array('message' => 'This content type cannot be saved')
      ));
      die;
    }

    // Validate content_id is a positive integer
    $contentId = (int) $contentId;
    if ($contentId <= 0) {
       echo json_encode(array(
        'error' => '1',
        'error_message' => 'invalid_content_id',
        'result' => array('message' => 'Invalid content identifier')
      ));
      die;
    }

    $viewer = Engine_Api::_()->user()->getViewer();

    try {
      $savedItem = Engine_Api::_()->getApi('savecollection', 'core')
        ->saveItem($viewer, $contentType, $contentId);

      $result = array(
        'status' => true,
        'saveditem_id' => $savedItem->getIdentity(),
        'body' => array(
          'saveditem_id' => $savedItem->getIdentity(),
          'user_id' => $savedItem->user_id,
          'content_type' => $savedItem->content_type,
          'content_id' => $savedItem->content_id,
          'created_at' => $savedItem->created_at,
        ),
      );

       echo json_encode(array(
        'error' => '0',
        'error_message' => '',
        'result' => $result
      ));die;
    } catch (Exception $e) {
       echo json_encode(array(
        'error' => '1',
        'error_message' => $e->getMessage(),
        'result' => ''
      ));die;
    }
  }

  /**
   * POST - Unsave a content item for the authenticated viewer.
   * Params: content_type, content_id
   */
  public function unsaveAction()
  {
    $contentType = $this->_getParam('content_type', '');
    $contentId = $this->_getParam('content_id', 0);

    // Validate content_type is not empty
    if (empty($contentType)) {
       echo json_encode(array(
        'error' => '1',
        'error_message' => 'invalid_content_type',
        'result' => array('message' => 'This content type cannot be saved')
      ));die;
    }

    // Validate content_id is a positive integer
    $contentId = (int) $contentId;
    if ($contentId <= 0) {
       echo json_encode(array(
        'error' => '1',
        'error_message' => 'invalid_content_id',
        'result' => array('message' => 'Invalid content identifier')
      ));die;
    }

    $viewer = Engine_Api::_()->user()->getViewer();

    try {
      Engine_Api::_()->getApi('savecollection', 'core')
        ->unsaveItem($viewer, $contentType, $contentId);

      $result = array('status' => true);

       echo json_encode(array(
        'error' => '0',
        'error_message' => '',
        'result' => $result
      ));die;
    } catch (Exception $e) {
       echo json_encode(array(
        'error' => '1',
        'error_message' => $e->getMessage(),
        'result' => ''
      ));die;
    }
  }

  /**
   * GET - Check if a content item is saved by the authenticated viewer.
   * Params: content_type, content_id
   */
  public function isSavedAction()
  {
    $contentType = $this->_getParam('content_type', '');
    $contentId = $this->_getParam('content_id', 0);

    // Validate content_type is not empty
    if (empty($contentType)) {
       echo json_encode(array(
        'error' => '1',
        'error_message' => 'invalid_content_type',
        'result' => array('message' => 'This content type cannot be saved')
      ));
      die;
    }

    // Validate content_id is a positive integer
    $contentId = (int) $contentId;
    if ($contentId <= 0) {
       echo json_encode(array(
        'error' => '1',
        'error_message' => 'invalid_content_id',
        'result' => array('message' => 'Invalid content identifier')
      ));die;
    }

    $viewer = Engine_Api::_()->user()->getViewer();

    try {
      $savedItem = Engine_Api::_()->getApi('savecollection', 'core')
        ->getSavedItem($viewer, $contentType, $contentId);

      $isSaved = ($savedItem !== null);
      $saveditemId = $isSaved ? $savedItem->getIdentity() : null;

      $result = array(
        'status' => true,
        'is_saved' => $isSaved,
        'saveditem_id' => $saveditemId,
      );

       echo json_encode(array(
        'error' => '0',
        'error_message' => '',
        'result' => $result
      ));die;
    } catch (Exception $e) {
       echo json_encode(array(
        'error' => '1',
        'error_message' => $e->getMessage(),
        'result' => ''
      ));die;
    }
  }

  /**
   * GET - List viewer's saved items with pagination and filtering.
   * Params: page, limit, search, sort, content_type
   */
  public function savedItemsAction()
  {
    $viewer = Engine_Api::_()->user()->getViewer();

    $params = array(
      'page' => $this->_getParam('page', 1),
      'limit' => $this->_getParam('limit', null),
      'search' => $this->_getParam('search', ''),
      'sort' => $this->_getParam('sort', ''),
      'content_type' => $this->_getParam('content_type', ''),
    );

    try {
      $paginator = Engine_Api::_()->getApi('savecollection', 'core')
        ->getSavedItems($viewer, $params);

      $items = array();
      foreach ($paginator as $savedItem) {
        $itemData = array(
          'saveditem_id' => $savedItem->saveditem_id,
          'content_type' => $savedItem->content_type,
          'content_id' => $savedItem->content_id,
          'created_at' => $savedItem->created_at,
        );

        // Try to resolve the actual content item for additional details
        try {
          $contentItem = Engine_Api::_()->getItem($savedItem->content_type, $savedItem->content_id);
          if ($contentItem && $contentItem->getIdentity()) {
            $itemData['title'] = $contentItem->getTitle();
            $itemData['photo'] = $contentItem->getPhotoUrl()
              ? $this->getBaseUrl(false, $contentItem->getPhotoUrl())
              : '';
          }
        } catch (Exception $e) {
          // Content may have been deleted or is inaccessible
          $itemData['title'] = '';
          $itemData['photo'] = '';
        }

        $items[] = $itemData;
      }

      $totalCount = $paginator->getTotalItemCount();
      $currentPage = $paginator->getCurrentPageNumber();
      $pageCount = $paginator->count();

      $result = array(
        'status' => true,
        'body' => $items,
        'totalCount' => $totalCount,
        'hasMore' => ($currentPage < $pageCount),
      );

       echo json_encode(array(
        'error' => '0',
        'error_message' => '',
        'result' => $result
      ));die;
    } catch (Exception $e) {
       echo json_encode(array(
        'error' => '1',
        'error_message' => $e->getMessage(),
        'result' => ''
      ));die;
    }
  }

  /**
   * POST - Create a new collection for the authenticated viewer.
   * Params: name
   */
  public function collectionCreateAction()
  {
    $viewer = Engine_Api::_()->user()->getViewer();
    $name = $this->_getParam('name', '');

    // Validate name is not empty
    if (empty(trim($name))) {
       echo json_encode(array(
        'error' => '1',
        'error_message' => 'name_required',
        'result' => array('message' => 'Collection name is required')
      ));
      die;
    }

    try {
      $collection = Engine_Api::_()->getApi('savecollection', 'core')
        ->createCollection($viewer, $name);

      $result = array(
        'status' => true,
        'collection_id' => $collection->getIdentity(),
        'body' => array(
          'collection_id' => $collection->getIdentity(),
          'name' => $collection->name,
          'usage_count' => (int) $collection->usage_count,
          'created_at' => $collection->created_at,
          'updated_at' => $collection->updated_at,
        ),
      );

       echo json_encode(array(
        'error' => '0',
        'error_message' => '',
        'result' => $result
      ));die;
    } catch (Core_Model_Exception $e) {
       echo json_encode(array(
        'error' => '1',
        'error_message' => $e->getMessage(),
        'result' => ''
      ));die;
    } catch (Exception $e) {
       echo json_encode(array(
        'error' => '1',
        'error_message' => $e->getMessage(),
        'result' => ''
      ));die;
    }
  }

  /**
   * POST - Rename an existing collection.
   * Params: collection_id, name
   */
  public function collectionEditAction()
  {
    $viewer = Engine_Api::_()->user()->getViewer();

    // Load and validate ownership
    $collectionId = (int) $this->_getParam('collection_id', 0);
    $collectionsTable = Engine_Api::_()->getDbtable('collections', 'core');
    $collection = $collectionsTable->find($collectionId)->current();

    if (!$collection || $collection->user_id != $viewer->getIdentity()) {
       echo json_encode(array(
        'error' => '1',
        'error_message' => 'collection_not_found',
        'result' => array('message' => 'Collection not found')
      ));die;
    }

    $name = $this->_getParam('name', '');

    // Validate name is not empty
    if (empty(trim($name))) {
       echo json_encode(array(
        'error' => '1',
        'error_message' => 'name_required',
        'result' => array('message' => 'Collection name is required')
      ));die;
    }

    try {
      $collection = Engine_Api::_()->getApi('savecollection', 'core')
        ->renameCollection($collection, $name);

      $result = array(
        'status' => true,
        'body' => array(
          'collection_id' => $collection->getIdentity(),
          'name' => $collection->name,
          'usage_count' => (int) $collection->usage_count,
          'created_at' => $collection->created_at,
          'updated_at' => $collection->updated_at,
        ),
      );

       echo json_encode(array(
        'error' => '0',
        'error_message' => '',
        'result' => $result
      ));die;
    } catch (Core_Model_Exception $e) {
       echo json_encode(array(
        'error' => '1',
        'error_message' => $e->getMessage(),
        'result' => ''
      ));die;
    } catch (Exception $e) {
       echo json_encode(array(
        'error' => '1',
        'error_message' => $e->getMessage(),
        'result' => ''
      ));die;
    }
  }

  /**
   * POST - Delete a collection.
   * Params: collection_id
   */
  public function collectionDeleteAction()
  {
    $viewer = Engine_Api::_()->user()->getViewer();

    // Load and validate ownership
    $collectionId = (int) $this->_getParam('collection_id', 0);
    $collectionsTable = Engine_Api::_()->getDbtable('collections', 'core');
    $collection = $collectionsTable->find($collectionId)->current();

    if (!$collection || $collection->user_id != $viewer->getIdentity()) {
       echo json_encode(array(
        'error' => '1',
        'error_message' => 'collection_not_found',
        'result' => array('message' => 'Collection not found')
      ));die;
    }

    try {
      Engine_Api::_()->getApi('savecollection', 'core')
        ->deleteCollection($collection);

      $result = array('status' => true);

       echo json_encode(array(
        'error' => '0',
        'error_message' => '',
        'result' => $result
      ));die;
    } catch (Exception $e) {
       echo json_encode(array(
        'error' => '1',
        'error_message' => $e->getMessage(),
        'result' => ''
      ));die;
    }
  }

  /**
   * POST - Add a saved item to one or more collections.
   * Params: saveditem_id, collection_ids (array)
   */
  public function addToCollectionsAction()
  {
    $viewer = Engine_Api::_()->user()->getViewer();

    $saveditemId = (int) $this->_getParam('saveditem_id', 0);
    $collectionIds = $this->_getParam('collection_ids', array());

    // Load saved item and validate ownership
    $saveditemsTable = Engine_Api::_()->getDbtable('saveditems', 'core');
    $savedItem = $saveditemsTable->find($saveditemId)->current();

    if (!$savedItem || $savedItem->user_id != $viewer->getIdentity()) {
       echo json_encode(array(
        'error' => '1',
        'error_message' => 'saveditem_not_found',
        'result' => array('message' => 'Saved item not found')
      ));die;
    }

    if (empty($collectionIds) || !is_array($collectionIds)) {
       echo json_encode(array(
        'error' => '0',
        'error_message' => '',
        'result' => array('status' => true, 'added_count' => 0)
      ));die;
    }

    try {
      $addedCount = Engine_Api::_()->getApi('savecollection', 'core')
        ->addToCollections($savedItem, $collectionIds);

      $result = array(
        'status' => true,
        'added_count' => $addedCount,
      );

       echo json_encode(array(
        'error' => '0',
        'error_message' => '',
        'result' => $result
      ));die;
    } catch (Core_Model_Exception $e) {
       echo json_encode(array(
        'error' => '1',
        'error_message' => $e->getMessage(),
        'result' => ''
      ));die;
    } catch (Exception $e) {
       echo json_encode(array(
        'error' => '1',
        'error_message' => $e->getMessage(),
        'result' => ''
      ));die;
    }
  }

  /**
   * POST - Remove a saved item from a specific collection.
   * Params: saveditem_id, collection_id
   */
  public function removeFromCollectionAction()
  {
    $viewer = Engine_Api::_()->user()->getViewer();

    $saveditemId = (int) $this->_getParam('saveditem_id', 0);
    $collectionId = (int) $this->_getParam('collection_id', 0);

    // Load saved item and validate ownership
    $saveditemsTable = Engine_Api::_()->getDbtable('saveditems', 'core');
    $savedItem = $saveditemsTable->find($saveditemId)->current();

    if (!$savedItem || $savedItem->user_id != $viewer->getIdentity()) {
       echo json_encode(array(
        'error' => '1',
        'error_message' => 'saveditem_not_found',
        'result' => array('message' => 'Saved item not found')
      ));die;
    }

    // Validate collection ownership
    $collectionsTable = Engine_Api::_()->getDbtable('collections', 'core');
    $collection = $collectionsTable->find($collectionId)->current();

    if (!$collection || $collection->user_id != $viewer->getIdentity()) {
       echo json_encode(array(
        'error' => '1',
        'error_message' => 'collection_not_found',
        'result' => array('message' => 'Collection not found')
      ));die;
    }

    try {
      Engine_Api::_()->getApi('savecollection', 'core')
        ->removeFromCollection($saveditemId, $collectionId);

      $result = array('status' => true);

       echo json_encode(array(
        'error' => '0',
        'error_message' => '',
        'result' => $result
      ));die;
    } catch (Exception $e) {
       echo json_encode(array(
        'error' => '1',
        'error_message' => $e->getMessage(),
        'result' => ''
      ));die;
    }
  }

  /**
   * GET - Get all viewer's collections for the Add to Collection sheet.
   * Returns up to 10 collections ordered by usage.
   */
  public function getCollectionsSheetAction()
  {
    $viewer = Engine_Api::_()->user()->getViewer();

    try {
      $api = Engine_Api::_()->getApi('savecollection', 'core');
      $collectionsTable = Engine_Api::_()->getDbtable('collections', 'core');
      $rowset = $collectionsTable->getByUsageOrder($viewer->getIdentity(), 10);

      $body = array();
      foreach ($rowset as $collection) {
        $body[] = array(
          'collection_id' => $collection->collection_id,
          'name' => $collection->name,
          'usage_count' => (int) $collection->usage_count,
        );
      }

      echo json_encode(array(
        'error' => '0',
        'error_message' => '',
        'result' => $body
      ));die;
    } catch (Exception $e) {
      echo json_encode(array(
        'error' => '1',
        'error_message' => $e->getMessage(),
        'result' => array()
      ));die;
    }
  }

  /**
   * GET - Get collections that contain a specific saved item.
   * Params: saveditem_id
   */
  public function collectionsForItemAction()
  {
    $viewer = Engine_Api::_()->user()->getViewer();

    $saveditemId = (int) $this->_getParam('saveditem_id', 0);

    // Load saved item and validate ownership
    $saveditemsTable = Engine_Api::_()->getDbtable('saveditems', 'core');
    $savedItem = $saveditemsTable->find($saveditemId)->current();

    if (!$savedItem || $savedItem->user_id != $viewer->getIdentity()) {
      echo json_encode(array(
        'error' => '1',
        'error_message' => 'saveditem_not_found',
        'result' => array('message' => 'Saved item not found')
      ));die;
    }

    try {
      $collections = Engine_Api::_()->getApi('savecollection', 'core')
        ->getCollectionsForItem($savedItem);

      $body = array();
      foreach ($collections as $collectionData) {
        $body[] = array(
          'collection_id' => $collectionData['collection_id'],
          'name' => $collectionData['name'],
          'usage_count' => (int) $collectionData['usage_count'],
        );
      }

      $result = array(
        'status' => true,
        'body' => $body,
      );

      echo json_encode(array(
        'error' => '0',
        'error_message' => '',
        'result' => $result
      ));die;
    } catch (Exception $e) {
      echo json_encode(array(
        'error' => '1',
        'error_message' => $e->getMessage(),
        'result' => ''
      ));die;
    }
  }

  /**
   * GET - List items in a specific collection with pagination, search, sort, and filter.
   * Params: collection_id, page, limit, search, sort, content_type
   */
  public function collectionItemsAction()
  {
    $viewer = Engine_Api::_()->user()->getViewer();

    // Load and validate ownership
    $collectionId = (int) $this->_getParam('collection_id', 0);
    $collectionsTable = Engine_Api::_()->getDbtable('collections', 'core');
    $collection = $collectionsTable->find($collectionId)->current();

    if (!$collection || $collection->user_id != $viewer->getIdentity()) {
      echo json_encode(array(
        'error' => '1',
        'error_message' => 'collection_not_found',
        'result' => array('message' => 'Collection not found')
      ));die;
    }

    $params = array(
      'page' => $this->_getParam('page', 1),
      'limit' => $this->_getParam('limit', null),
      'search' => $this->_getParam('search', ''),
      'sort' => $this->_getParam('sort', ''),
      'content_type' => $this->_getParam('content_type', ''),
    );

    try {
      $paginator = Engine_Api::_()->getApi('savecollection', 'core')
        ->getCollectionItems($collection, $params);

      $items = array();
      foreach ($paginator as $collectionItem) {
        $itemData = array(
          'collectionitem_id' => $collectionItem->collectionitem_id,
          'saveditem_id' => $collectionItem->saveditem_id,
          'created_at' => $collectionItem->created_at,
        );

        // Resolve the saved item to get content details
        try {
          $saveditemsTable = Engine_Api::_()->getDbtable('saveditems', 'core');
          $savedItem = $saveditemsTable->find($collectionItem->saveditem_id)->current();

          if ($savedItem) {
            $itemData['content_type'] = $savedItem->content_type;
            $itemData['content_id'] = $savedItem->content_id;

            // Try to resolve the actual content item for title and photo
            try {
              $contentItem = Engine_Api::_()->getItem($savedItem->content_type, $savedItem->content_id);
              if ($contentItem && $contentItem->getIdentity()) {
                $itemData['title'] = $contentItem->getTitle();
                $itemData['photo'] = $contentItem->getPhotoUrl()
                  ? $this->getBaseUrl(false, $contentItem->getPhotoUrl())
                  : '';
              } else {
                $itemData['title'] = '';
                $itemData['photo'] = '';
              }
            } catch (Exception $e) {
              $itemData['title'] = '';
              $itemData['photo'] = '';
            }
          } else {
            $itemData['content_type'] = '';
            $itemData['content_id'] = 0;
            $itemData['title'] = '';
            $itemData['photo'] = '';
          }
        } catch (Exception $e) {
          $itemData['content_type'] = '';
          $itemData['content_id'] = 0;
          $itemData['title'] = '';
          $itemData['photo'] = '';
        }

        $items[] = $itemData;
      }

      $totalCount = $paginator->getTotalItemCount();
      $currentPage = $paginator->getCurrentPageNumber();
      $pageCount = $paginator->count();

      $result = array(
        'status' => true,
        'body' => $items,
        'totalCount' => $totalCount,
        'hasMore' => ($currentPage < $pageCount),
      );

      echo json_encode(array(
        'error' => '0',
        'error_message' => '',
        'result' => $result
      ));die;
    } catch (Exception $e) {
       echo json_encode(array(
        'error' => '1',
        'error_message' => $e->getMessage(),
        'result' => ''
      ));die;
    }
  }
}
