<?php

namespace App\Models;

use App\Core\Model;

class ContactSubmission extends Model
{
    protected static string $table = 'iw_contact_submissions';

    /**
     * Paginated list for admin (newest first).
     *
     * @return array{items: array, total: int, page: int, perPage: int, pages: int}
     */
    public static function paginated(int $page = 1, int $perPage = 20): array
    {
        $page    = max(1, $page);
        $perPage = max(1, min(100, $perPage));
        $offset  = ($page - 1) * $perPage;

        $total = (int) static::db()->fetch(
            "SELECT COUNT(*) AS c FROM iw_contact_submissions"
        )['c'];

        $items = static::db()->fetchAll(
            "SELECT id, ip_address, is_read, created_at,
                    LEFT(form_data, 500) AS form_data_preview
             FROM iw_contact_submissions
             ORDER BY created_at DESC
             LIMIT " . (int) $perPage . " OFFSET " . (int) $offset
        );

        return [
            'items'   => $items,
            'total'   => $total,
            'page'    => $page,
            'perPage' => $perPage,
            'pages'   => (int) ceil($total / $perPage),
        ];
    }

    /**
     * Single submission by ID (full form_data).
     */
    public static function findById(int $id): ?array
    {
        return static::db()->fetch(
            "SELECT * FROM iw_contact_submissions WHERE id = :id",
            ['id' => $id]
        ) ?: null;
    }

    /**
     * Mark a submission as read.
     */
    public static function markRead(int $id): void
    {
        static::db()->query(
            "UPDATE iw_contact_submissions SET is_read = 1 WHERE id = :id",
            ['id' => $id]
        );
    }

    /**
     * Mark multiple submissions as read.
     *
     * @param int[] $ids
     */
    public static function bulkMarkRead(array $ids): int
    {
        if (empty($ids)) {
            return 0;
        }
        $ids        = array_map('intval', $ids);
        $placeholders = implode(',', array_fill(0, count($ids), '?'));
        static::db()->query(
            "UPDATE iw_contact_submissions SET is_read = 1 WHERE id IN ({$placeholders})",
            $ids
        );
        return count($ids);
    }

    /**
     * Count of unread submissions (for nav badge).
     */
    public static function countUnread(): int
    {
        return (int) static::db()->fetch(
            "SELECT COUNT(*) AS c FROM iw_contact_submissions WHERE is_read = 0"
        )['c'];
    }

    /**
     * Delete a single submission.
     */
    public static function deleteById(int $id): int
    {
        static::db()->query(
            "DELETE FROM iw_contact_submissions WHERE id = :id",
            ['id' => $id]
        );
        return 1;
    }

    /**
     * Bulk-delete submissions.
     *
     * @param int[] $ids
     */
    public static function bulkDelete(array $ids): int
    {
        if (empty($ids)) {
            return 0;
        }
        $ids          = array_map('intval', $ids);
        $placeholders = implode(',', array_fill(0, count($ids), '?'));
        static::db()->query(
            "DELETE FROM iw_contact_submissions WHERE id IN ({$placeholders})",
            $ids
        );
        return count($ids);
    }

    /**
     * All submissions for CSV export (full form_data).
     */
    public static function allForExport(): array
    {
        return static::db()->fetchAll(
            "SELECT id, form_data, ip_address, is_read, created_at
             FROM iw_contact_submissions
             ORDER BY created_at DESC"
        );
    }

    /**
     * Save a new submission. Returns the inserted ID.
     *
     * @param array $fieldData  Array of ['id','label','value','type'] entries
     */
    public static function create(array $fieldData, string $ip = '', string $ua = ''): int
    {
        $db = static::db();
        $db->query(
            "INSERT INTO iw_contact_submissions (form_data, ip_address, user_agent, is_read, created_at)
             VALUES (?, ?, ?, 0, NOW())",
            [
                json_encode($fieldData, JSON_UNESCAPED_UNICODE),
                $ip ?: null,
                $ua ? mb_substr($ua, 0, 500) : null,
            ]
        );
        return (int) $db->lastInsertId();
    }
}
