<?php
namespace app\models;

use app\app;

class subscriptions
{
    const STATES = [
        'TRIAL', 'START', 'RENEWAL',
    ];

    const STATUS = [
        'COMPLETED', 'CANCELED',
    ];

    public static function init()
    {
        app::$db->exec("CREATE TABLE IF NOT EXISTS subscriptions (
            subscription_id INTEGER PRIMARY KEY AUTOINCREMENT,
            user_id INTEGER NOT NULL,
            product_id INTEGER NOT NULL,
            start_date DATETIME NOT NULL,
            renews_at DATETIME NOT NULL,
            status TEXT CHECK(status IN ('" . implode("', '", self::STATUS) . "')) NOT NULL DEFAULT 'COMPLETED',
            state TEXT CHECK(state IN ('" . implode("', '", self::STATES) . "')) NOT NULL DEFAULT 'TRIAL',
            invoice_date DATETIME NOT NULL,
            FOREIGN KEY (user_id) REFERENCES users(id),
            FOREIGN KEY (product_id) REFERENCES products(id)
        );");
    }

    public static function createSubscription($userId, $productId, $state, $startDate, $renewAt, $invoiceDate)
    {
        self::validateState($state);
        self::validateStatus($status);

        $stmt = app::$db->prepare("INSERT INTO subscriptions (user_id, product_id, state, status, start_date, renews_at, invoice_date)
                                   VALUES (:user_id, :product_id, :state, :status, :start_date, :renews_at, :invoice_date)");
        $stmt->execute([
            'user_id'      => $userId,
            'product_id'   => $productId,
            'state'        => $state,
            'status'       => $status,
            'start_date'   => $startDate,
            'renews_at'    => $renewAt,
            'invoice_date' => $invoiceDate,
        ]);

        return app::$db->lastInsertId();
    }

    public static function updateState(int $subscriptionId, string $state)
    {
        self::validateState($state);

        $stmt = app::$db->prepare("UPDATE subscriptions SET state = :state WHERE subscription_id = :subscription_id");
        $stmt->execute([
            'subscription_id' => $subscriptionId,
            'state'           => $state,
        ]);
    }

    public static function updateStatus(int $subscriptionId, string $status)
    {
        self::validateStatus($status);

        $stmt = app::$db->prepare("UPDATE subscriptions SET status = :status WHERE subscription_id = :subscription_id");
        $stmt->execute([
            'subscription_id' => $subscriptionId,
            'status'          => $status,
        ]);
    }

    public static function getSubscription(int $subscriptionId): array
    {
        $stmt = app::$db->prepare("SELECT * FROM subscriptions WHERE subscription_id = :subscription_id");
        $stmt->execute(['subscription_id' => $subscriptionId]);
        return $stmt->fetch() ?: [];
    }

    public static function getUserSubscriptions(int $userId): array
    {
        $stmt = app::$db->prepare("SELECT * FROM subscriptions WHERE user_id = :user_id ORDER BY start_date DESC");
        $stmt->execute(['user_id' => $userId]);
        return $stmt->fetchAll();
    }

    private static function validateState(string $state)
    {
        if (! in_array($state, self::STATES, true)) {
            throw new \InvalidArgumentException("Invalid subscription state: $state");
        }
    }

    private static function validateStatus(string $status)
    {
        if (! in_array($status, self::STATUS, true)) {
            throw new \InvalidArgumentException("Invalid subscription status: $status");
        }
    }
}
