<?php
namespace app\controllers;

use app\models\categories;
use app\models\emails;
use app\models\products;
use app\models\subscriptions;
use app\models\transactions;
use app\models\users;

class admin
{
    public static function index($defaults)
    {
        echo $GLOBALS['twig']->render('lib/pages/index.twig', array_merge($defaults, [
            'child_template' => 'admin/index.twig',
            'page_title'     => 'Dashboard',
            'breadcrumbs'    => [
                [
                    'url'   => '/admin',
                    'title' => 'Admin',
                ],
            ],
        ]));
    }

    public static function users($defaults)
    {
        echo $GLOBALS['twig']->render('lib/pages/index.twig', array_merge($defaults, [
            'child_template' => 'admin/users.twig',
            'page_title'     => 'Users',
            'users'          => users::getUsers(20),
            'breadcrumbs'    => [
                [
                    'url'   => '/admin',
                    'title' => 'Admin',
                ],
                [
                    'url'   => '/admin/users',
                    'title' => 'Users',
                ],
            ],
        ]));
    }

    public static function products($defaults)
    {
        echo $GLOBALS['twig']->render('lib/pages/index.twig', array_merge($defaults, [
            'child_template' => 'admin/products/index.twig',
            'page_title'     => 'Products',
            'categories'     => categories::getTree(),
            'products'       => products::get(20),
            'breadcrumbs'    => [
                [
                    'url'   => '/admin',
                    'title' => 'Admin',
                ],
                [
                    'url'   => '/admin/products',
                    'title' => 'Products',
                ],
            ],
        ]));
    }

    public static function products_add($defaults)
    {
        if ($_SERVER['REQUEST_METHOD'] == 'POST') {
            $_SESSION['last_post'] = $_POST;
            $valid                 = products::validateProductData($_POST);
            if (! empty($valid['errors'])) {
                $_SESSION['error'] = implode(' ', $valid['errors']);
                header('Location: /admin/products/add');
                exit;
            }
            products::add($valid);
            $_SESSION['success'] = 'Product added successfully.';
            unset($_SESSION['last_post']);
            header('Location: /admin/products/add');
            exit;
        }
        echo $GLOBALS['twig']->render('lib/pages/index.twig', array_merge($defaults, [
            'child_template' => 'admin/products/add.twig',
            'page_title'     => 'Add a Product',
            'categories'     => categories::getOptions(),
            'breadcrumbs'    => [
                [
                    'url'   => '/admin',
                    'title' => 'Admin',
                ],
                [
                    'url'   => '/admin/products',
                    'title' => 'Products',
                ],
                [
                    'url'   => '/admin/products/add',
                    'title' => 'Add Product',
                ],
            ],
        ]));
    }

    public static function products_edit($defaults, $id)
    {
        if ($_SERVER['REQUEST_METHOD'] == 'POST') {
            $_SESSION['last_post'] = $_POST;
            $valid                 = products::validateProductData($_POST);

            if (! empty($valid['errors'])) {
                $_SESSION['error'] = implode(' ', $valid['errors']);
                header("Location: /admin/products/edit/$id");
                exit;
            }
            products::update($id, $valid);
            $_SESSION['success'] = 'Product updated successfully.';
            unset($_SESSION['last_post']);
            header("Location: /admin/products/edit/$id");
            exit;
        }
        $product = products::getById($id);

        echo $GLOBALS['twig']->render('lib/pages/index.twig', array_merge($defaults, [
            'child_template' => 'admin/products/edit.twig',
            'page_title'     => 'Edit Product',
            'product'        => $product,
            'categories'     => categories::getOptions(),
            'breadcrumbs'    => [
                [
                    'url'   => '/admin',
                    'title' => 'Admin',
                ],
                [
                    'url'   => '/admin/products',
                    'title' => 'Products',
                ],
                [
                    'url'   => "/admin/products/edit/$id",
                    'title' => 'Edit Product',
                ],
            ],
        ]));
    }

    public static function categories($defaults)
    {
        echo $GLOBALS['twig']->render('lib/pages/index.twig', array_merge($defaults, [
            'child_template' => 'admin/categories/index.twig',
            'page_title'     => 'Categories',
            'categories'     => categories::getTree(),
            'breadcrumbs'    => [
                [
                    'url'   => '/admin',
                    'title' => 'Admin',
                ],
                [
                    'url'   => '/admin/categories',
                    'title' => 'Categories',
                ],
            ],
        ]));
    }

    public static function categories_add($defaults)
    {
        if ($_SERVER['REQUEST_METHOD'] == 'POST') {
            $parent_id = $_POST['parent_id'] ?? null;
            $label     = $_POST['label'] ?? null;
            $value     = $_POST['value'] ?? null;
            if (! $label || ! $value) {
                $_SESSION['error'] = 'Title and slug are required fields.';
                header('Location: /admin/categories/add');
                exit;
            }
            categories::add($label, $value, $parent_id);
            $_SESSION['success'] = 'Category added successfully.';
            header('Location: /admin/categories/add');
            exit;
        }
        echo $GLOBALS['twig']->render('lib/pages/index.twig', array_merge($defaults, [
            'child_template' => 'admin/categories/add.twig',
            'page_title'     => 'Add a Category',
            'categories'     => categories::getOptions(),
            'breadcrumbs'    => [
                [
                    'url'   => '/admin',
                    'title' => 'Admin',
                ],
                [
                    'url'   => '/admin/products',
                    'title' => 'Products',
                ],
                [
                    'url'   => null,
                    'title' => 'Add Category',
                ],
            ],
        ]));
    }

    public static function categories_edit($defaults, $cat_id)
    {
        if ($_SERVER['REQUEST_METHOD'] == 'POST') {
            $parent_id = $_POST['parent_id'] ?? null;
            $label     = $_POST['label'] ?? null;
            $value     = $_POST['value'] ?? null;
            if (! $label || ! $value) {
                $_SESSION['error'] = 'Title and slug are required fields.';
                header('Location: /admin/categories/edit/' . $cat_id);
                exit;
            }
            if ($cat_id == $parent_id) {
                $_SESSION['error'] = 'A category cannot be its own parent.';
                header('Location: /admin/categories/edit/' . $cat_id);
                exit;
            }
            categories::updateById($cat_id, $label, $value, $parent_id);
            $_SESSION['success'] = 'Category updated successfully.';
            header('Location: /admin/categories/edit/' . $cat_id);
            exit;
        }
        echo $GLOBALS['twig']->render('lib/pages/index.twig', array_merge($defaults, [
            'child_template' => 'admin/categories/edit.twig',
            'page_title'     => 'Edit Category',
            'category'       => categories::getById($cat_id),
            'categories'     => categories::getOptions(),
            'breadcrumbs'    => [
                [
                    'url'   => '/admin',
                    'title' => 'Admin',
                ],
                [
                    'url'   => '/admin/categories',
                    'title' => 'Categories',
                ],
                [
                    'url'   => null,
                    'title' => 'Edit',
                ],
            ],
        ]));
    }

    public static function returns($defaults)
    {
        echo $GLOBALS['twig']->render('lib/pages/index.twig', array_merge($defaults, [
            'child_template' => 'admin/returns.twig',
            'page_title'     => 'Returns',
            'breadcrumbs'    => [
                [
                    'url'   => '/admin',
                    'title' => 'Admin',
                ],
                [
                    'url'   => '/admin/returns',
                    'title' => 'Returns',
                ],
            ],
        ]));
    }

    public static function transactions($defaults)
    {
        echo $GLOBALS['twig']->render('lib/pages/index.twig', array_merge($defaults, [
            'child_template'  => 'admin/transactions/index.twig',
            'page_title'      => 'Transactions',
            'recent_sats'     => transactions::getRecent(10, 'sats'),
            'recent_cents'    => transactions::getRecent(10, 'cents'),
            'whales_sats'     => transactions::getWhales(10, 'sats'),
            'whales_cents'    => transactions::getWhales(10, 'cents'),
            'sats_liability'  => transactions::getLiabilities('sats'),
            'cents_liability' => transactions::getLiabilities('cents'),
            'breadcrumbs'     => [
                [
                    'url'   => '/admin',
                    'title' => 'Admin',
                ],
                [
                    'url'   => '/admin/transactions',
                    'title' => 'Transactions',
                ],
            ],
        ]));
    }

    public static function transactions_add($defaults)
    {
        if ($_SERVER['REQUEST_METHOD'] == 'POST') {
            $amount          = $_POST['amount'] ?? null;
            $currency        = $_POST['currency'];
            $user_identifier = $_POST['user_identifier'] ?? null;
            if (! $amount || ! $user_identifier) {
                $_SESSION['error'] = ! $amount ? "Please enter an amount for the transaction." : "Please enter a user email or id for the transaction.";
            } else {
                if (strpos($user_identifier, '@') !== false && strpos($user_identifier, '.') !== false) {
                    $user = users::getByEmail($user_identifier);
                } elseif (is_numeric($user_identifier)) {
                    $user = users::getById((int) $user_identifier);
                } else {
                    $_SESSION['error'] = "Invalid user identifier. Please enter a valid email or user ID.";
                }
                if (! $user) {
                    $_SESSION['error'] = "User not found. Please enter a valid email or user ID.";
                } else {
                    // create the transaction
                    $txid = transactions::add($user['id'], $amount > 0 ? 'CREDIT' : 'REVOKE', $currency == 'cents' ? $amount : 0, $currency == 'sats' ? $amount : 0);
                    header('Location: /transaction/' . $txid);
                    exit;
                }
            }
        }
        echo $GLOBALS['twig']->render('lib/pages/index.twig', array_merge($defaults, [
            'child_template' => 'admin/transactions/add.twig',
            'page_title'     => 'Add a Transaction',
            'breadcrumbs'    => [
                [
                    'url'   => '/admin',
                    'title' => 'Admin',
                ],
                [
                    'url'   => '/admin/transactions',
                    'title' => 'Transactions',
                ],
                [
                    'url'   => '/admin/transactions/add',
                    'title' => 'Add',
                ],
            ],
        ]));
        exit;
    }

    public static function emails($defaults)
    {
        $recent_emails = emails::getRecent(20);
        echo $GLOBALS['twig']->render('lib/pages/index.twig', array_merge($defaults, [
            'child_template' => 'admin/emails.twig',
            'page_title'     => 'Emails',
            'recent_emails'  => $recent_emails,
            'breadcrumbs'    => [
                [
                    'url'   => '/admin',
                    'title' => 'Admin',
                ],
                [
                    'url'   => '/admin/emails',
                    'title' => 'Emails',
                ],
            ],
        ]));
    }

    public static function transactions_reset($defaults)
    {
        $_SESSION['last_post'] = null;
        header('Location: /admin/transactions/add');
        exit;
    }

    public static function subscriptions($defaults)
    {
        echo $GLOBALS['twig']->render('lib/pages/index.twig', array_merge($defaults, [
            'child_template'     => 'admin/subscriptions/index.twig',
            'page_title'         => 'Subscriptions',
            'recent'             => subscriptions::getRecent(20),
            'upcoming'           => subscriptions::getUpcoming(20),
            'revenue'            => subscriptions::getTotalRevenue(),
            'active_count'       => subscriptions::getActiveCount(),
            'projected_revenue'  => subscriptions::getProjectedRevenue(),
            'breadcrumbs'        => [
                [
                    'url'   => '/admin',
                    'title' => 'Admin',
                ],
                [
                    'url'   => '/admin/subscriptions',
                    'title' => 'Subscriptions',
                ],
            ],
        ]));
    }

    public static function subscriptions_add($defaults)
    {
        if ($_SERVER['REQUEST_METHOD'] == 'POST') {
            $_SESSION['last_post'] = $_POST;

            $user_identifier = $_POST['user_identifier'] ?? null;
            $product_id      = $_POST['product_id'] ?? null;
            $frequency       = $_POST['frequency'] ?? null;
            $state           = $_POST['state'] ?? 'START';

            if (! $user_identifier || ! $product_id) {
                $_SESSION['error'] = 'User identifier and subscription product are required.';
                header('Location: /admin/subscriptions/add');
                exit;
            }

            // Resolve user
            $user = null;
            if (strpos($user_identifier, '@') !== false && strpos($user_identifier, '.') !== false) {
                $user = users::getByEmail($user_identifier);
            } elseif (is_numeric($user_identifier)) {
                $user = users::getById((int) $user_identifier);
            }

            if (! $user) {
                $_SESSION['error'] = 'User not found. Please enter a valid email or user ID.';
                header('Location: /admin/subscriptions/add');
                exit;
            }

            $now       = date('Y-m-d H:i:s');
            $renewAt   = self::calculateRenewDate($now, $frequency ?: 'month');

            $subId = subscriptions::createSubscription(
                $user['id'],
                (int) $product_id,
                $state,
                $now,
                $renewAt,
                $now
            );

            $_SESSION['success'] = 'Subscription created successfully.';
            unset($_SESSION['last_post']);
            header('Location: /admin/subscriptions');
            exit;
        }

        echo $GLOBALS['twig']->render('lib/pages/index.twig', array_merge($defaults, [
            'child_template'        => 'admin/subscriptions/add.twig',
            'page_title'            => 'Add Subscription',
            'subscription_products' => subscriptions::getSubscriptionProducts(),
            'breadcrumbs'           => [
                [
                    'url'   => '/admin',
                    'title' => 'Admin',
                ],
                [
                    'url'   => '/admin/subscriptions',
                    'title' => 'Subscriptions',
                ],
                [
                    'url'   => '/admin/subscriptions/add',
                    'title' => 'Add',
                ],
            ],
        ]));
    }

    private static function calculateRenewDate(string $startDate, string $frequency): string
    {
        $date = new \DateTime($startDate);
        switch ($frequency) {
            case 'minute': $date->modify('+1 minute'); break;
            case 'hour':   $date->modify('+1 hour'); break;
            case 'day':    $date->modify('+1 day'); break;
            case 'week':   $date->modify('+1 week'); break;
            case 'month':  $date->modify('+1 month'); break;
            case 'year':   $date->modify('+1 year'); break;
            default:       $date->modify('+1 month'); break;
        }
        return $date->format('Y-m-d H:i:s');
    }
}
