<?php

namespace classes;
require_once WD . '/modules/attachments/attachments_c.php';

use attachments\helpers\attachment_content;
use Exception;
use interfaces\attachments_i;
use attachments\helpers\attachment;
use attachments\attachments_c;
use objects\object_attachments_o;

class attachments implements attachments_i
{
    /**
     * The configuration of the module
     * @var attachments_c $config
     */
    public attachments_c $config;
    public function __construct()
    {
        $this->config = new attachments_c();
    }

    /**
     * @inheritDoc
     */
    public function list(string $type, int $object_id, array $options = []): array
    {
        if (count($options) === 0) {
            $options = ['id', 'content', 'created_at', 'object_id', 'object_type', 'created_at', 'updated_at']; // Default fields to return
        }
        return array_map(function ($item) {
            $item = (object)$item;
            $item->content = json_decode($item->content, true); // Decode JSON content
            return (new attachment())->populate((object)$item);
        }, (new object_attachments_o())->getFieldsWhere([
            'object_type' => $type,
            'object_id' => $object_id,
            'deleted_at' => null
        ], $options));
    }

    /**
     * @inheritDoc
     * @throws Exception If the attachment is not found
     */
    public function get(int $attachment_id): ?object_attachments_o
    {
        return (new object_attachments_o())->select($attachment_id) ?: null;
    }
    /**
     * Format an object_attachments_o to an attachment object
     * @param object_attachments_o $object_attachments_o The object to format
     * @return attachment The formatted attachment
     * @throws Exception If the attachment cannot be formatted
     */
    public function format(object_attachments_o $object_attachments_o): attachment
    {
        $data = (object)$object_attachments_o->toArray();
        // If content is JSON, decode it
        if (is_string($data->content) && $data->content !== '' && $data->content[0] === '{') {
            $data->content = json_decode($data->content, true);
        }
        return (new attachment())->populate($data);
    }

    /**
     * @inheritDoc
     * @throws Exception If the attachment cannot be created
     */
    public function create(string $type, int $object_id, attachment_content $attachment_content): int|bool
    {
        $object_attachments_o = new object_attachments_o();
        $object_attachments_o->add([
            'object_type' => $type,
            'object_id' => $object_id,
            'content' => json_encode($attachment_content->toArray()), // Store as JSON
        ]);
        return $object_attachments_o->id ?: false;
    }

    /**
     * @inheritDoc
     * @throws Exception If the attachment cannot be deleted
     */
    public function delete(int $attachment_id): bool
    {
        $object_attachments_o = new object_attachments_o();
        if ($object_attachments_o->select($attachment_id)) {
            $object_attachments_o->delete();
            return true;
        }
        return false;
    }

    /**
     * @inheritDoc
     * @throws Exception If the attachment cannot be updated
     */
    public function update(int $attachment_id, attachment_content $attachment_content): bool
    {
        $object_attachments_o = new object_attachments_o();
        if ($object_attachments_o->select($attachment_id)) {
            $object_attachments_o->content->set(json_encode($attachment_content->toArray()));
            return true;
        }
        return false;
    }
}