<?php

namespace Modules\Posts\Models;

use CodeIgniter\Model;

class PostBlocksModel extends Model
{

  protected $table = 'post_blocks';
  protected $primaryKey = 'id';

  protected $allowedFields = ['post_id', 'block_type', 'block_cat', 'content', 'heading', 'heading_type', 'color', 'photo', 'caption', 'list_type', 'code', 'advert_code',  'ordering', 'status'];

  protected $returnType     = 'array';
  protected $useTimestamps  = true;
  protected $useSoftDeletes = true;
  
  protected $createdField  = 'created_at';
  protected $updatedField  = 'updated_at';
  protected $deletedField  = 'deleted_at';


  public function getSingleBlockPost($post)
  {
      $builder = $this->db->table('post_blocks');
      $builder->select('post_blocks.*, posts.title')
              ->join('posts', 'posts.id=post_blocks.post_id')
              ->where('post_blocks.deleted_at', null)
              ->where('post_blocks.post_id', $post);
      $blocks = $builder->get()->getResult();

      // Attach child items to each block
      foreach ($blocks as &$block) {
          if (in_array($block->block_type, ['cards', 'stats', 'gallery'])) {
              $block->children = $this->db->table('post_block_items')
                  ->where('deleted_at', null)
                  ->where('block_id', $block->id)
                  ->orderBy('ordering', 'ASC')
                  ->get()
                  ->getResult();
          }
      }

      return $blocks;
  }

    /**
     * Get next ordering number for a given post_id
     */
    public function getNextOrdering($post_id)
    {
        $maxOrder = $this->where('post_id', $post_id)
                         ->selectMax('ordering')
                         ->first();

        return isset($maxOrder['ordering']) ? ($maxOrder['ordering'] + 1) : 1;
    }

    /**
     * Insert a new block with auto-ordering
     */
    public function insertWithOrdering($data)
    {
        if (!isset($data['post_id'])) {
            throw new \Exception("post_id is required.");
        }

        $data['ordering'] = $this->getNextOrdering($data['post_id']);

        return $this->insert($data);
    }

    /**
     * Reorder blocks after deletion or manual reordering
     */
    public function reorderBlocks($post_id)
    {
        $blocks = $this->where('post_id', $post_id)
                       ->orderBy('ordering', 'ASC')
                       ->findAll();

        $counter = 1;
        foreach ($blocks as $block) {
            $this->update($block['id'], ['ordering' => $counter]);
            $counter++;
        }
    }

    protected function shiftOrdering($postId, $newOrder, $blockId)
    {
        // Get all blocks ordered by ordering
        $blocks = $this->where('post_id', $postId)
                    ->where('id !=', $blockId)
                    ->orderBy('ordering', 'ASC')
                    ->findAll();

        $order = 1;
        foreach ($blocks as $b) {
            if ($order == $newOrder) {
                $order++; // leave space for updated block
            }
            $this->update($b['id'], ['ordering' => $order]);
            $order++;
        }
    }


    public function updateWithOrdering($id, $data)
    {
        // Get existing block info
        $block = $this->find($id);

        if (!$block) {
            return false; // Block not found
        }

        $postIdChanged = isset($data['post_id']) && $data['post_id'] != $block['post_id'];
        $orderingChanged = isset($data['ordering']) && $data['ordering'] != $block['ordering'];

        // If block moved to another post OR ordering changed
        if ($postIdChanged || $orderingChanged) {

            // If moved to another post, insert at bottom of that post's list
            if ($postIdChanged) {
                $maxOrder = $this->where('post_id', $data['post_id'])->selectMax('ordering')->first();
                $data['ordering'] = $maxOrder['ordering'] ? $maxOrder['ordering'] + 1 : 1;

                // Reorder old post list
                $this->reorderBlocks($block['post_id']);
            } 
            // If ordering manually changed in same post, shift others
            elseif ($orderingChanged) {
                $this->shiftOrdering($block['post_id'], $data['ordering'], $id);
            }
        }

        // Finally update
        return $this->update($id, $data);
    }

    /**
     * Delete a block and reorder remaining
     */
    public function deleteAndReorder($id)
    {
        // Get post_id of the block
        $block = $this->find($id);
        if (!$block) {
            return false;
        }

        $post_id = $block['post_id'];

        // Delete the block
        $this->delete($id);

        // Reorder remaining
        $this->reorderBlocks($post_id);

        return true;
    }


}