<?php

namespace LinkFiliate\Core;

if (!defined('ABSPATH')) {
	exit;
}

use LinkFiliate\App\Traits\Singleton;

/**
 * Handles plugin installation and database setup
 * 
 * @package LinkFiliate\Core
 */
class Install
{
	use Singleton;

	/**
	 * Plugin base name for table prefixes
	 */
	private const BASE = 'linkfiliate';

	/**
	 * Database table names
	 */
	private array $tables = [];

	/**
	 * Initialize installation process
	 *
	 * @return void
	 */
	public function init(): void
	{
		$this->setup_table_names();
		$this->install_pages();
		$this->install_tables();
		$this->insert_default_data();
	}

	/**
	 * Setup dynamic table names
	 *
	 * @return void
	 */
	private function setup_table_names(): void
	{
		global $wpdb;

		$this->tables = [
			'campaigns'     => "{$wpdb->prefix}" . self::BASE . "_campaigns",
			'clicks'     => "{$wpdb->prefix}" . self::BASE . "_clicks",
			'categories'    => "{$wpdb->prefix}" . self::BASE . "_categories",
			'settings'      => "{$wpdb->prefix}" . self::BASE . "_settings",
			'integrations'  => "{$wpdb->prefix}" . self::BASE . "_integrations",
		];
	}

	/**
	 * Install required pages
	 *
	 * @return void
	 */
	private function install_pages(): void
	{
		// Uncomment and configure as needed
		// linkfilliate_install_page(
		//     'Frontend Template',
		//     'frontend-template',
		//     'template-frontend.php'
		// );
	}

	/**
	 * Create all database tables
	 *
	 * @return void
	 */
	private function install_tables(): void
	{
		global $wpdb;

		$charset_collate = $wpdb->get_charset_collate();

		require_once ABSPATH . 'wp-admin/includes/upgrade.php';

		// Create each table
		dbDelta($this->get_campaigns_table_sql($charset_collate));
		dbDelta($this->get_categories_table_sql($charset_collate));
		dbDelta($this->get_clicks_table_sql($charset_collate));
		dbDelta($this->get_settings_table_sql($charset_collate));
		dbDelta($this->get_integrations_table_sql($charset_collate));
	}

	/**
	 * Get campaigns table SQL
	 *
	 * @param string $charset_collate
	 * @return string
	 */
	private function get_campaigns_table_sql(string $charset_collate): string
	{
		return "CREATE TABLE IF NOT EXISTS {$this->tables['campaigns']} (
            id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
            name VARCHAR(255) NOT NULL,
            slug VARCHAR(255) NOT NULL,
            category_id BIGINT(20) UNSIGNED DEFAULT NULL,
            status ENUM('active', 'inactive', 'draft') NOT NULL DEFAULT 'active',
            description TEXT,
            rules TEXT,
            settings TEXT DEFAULT NULL,
			target_url VARCHAR(2083) DEFAULT NULL,
    		redirect_type ENUM('301', '302','307') NOT NULL DEFAULT '302',
            created_by BIGINT(20) UNSIGNED DEFAULT NULL,
            created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
            updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
            PRIMARY KEY (id),
            UNIQUE KEY slug (slug),
            KEY status (status),
            KEY category_id (category_id),
            KEY created_by (created_by)
        ) {$charset_collate};";
	}

	/**
	 * Get categories table SQL
	 *
	 * @param string $charset_collate
	 * @return string
	 */
	private function get_categories_table_sql(string $charset_collate): string
	{
		return "CREATE TABLE IF NOT EXISTS {$this->tables['categories']} (
            id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
            name VARCHAR(255) NOT NULL,
            slug VARCHAR(255) NOT NULL,
			status ENUM('active', 'inactive') NOT NULL DEFAULT 'active',
            description TEXT,
            parent_id BIGINT(20) UNSIGNED DEFAULT NULL,
            sort_order INT(11) DEFAULT 0,
            created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
            updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
            PRIMARY KEY (id),
            UNIQUE KEY slug (slug),
            KEY parent_id (parent_id),
            KEY sort_order (sort_order)
        ) {$charset_collate};";
	}



	/**
	 * Get clicks table SQL
	 *
	 * @param string $charset_collate
	 * @return string
	 */
	private function get_clicks_table_sql(string $charset_collate): string
	{
		return "CREATE TABLE IF NOT EXISTS {$this->tables['clicks']} (
            id CHAR(36) NOT NULL,
            visitor_id CHAR(36) DEFAULT NULL,
            campaign_id BIGINT(20) UNSIGNED DEFAULT NULL,
            ip_address VARCHAR(45) DEFAULT NULL,
            user_agent TEXT DEFAULT NULL,
            referrer TEXT DEFAULT NULL,
			host VARCHAR(255) DEFAULT NULL,
			uri VARCHAR(255) DEFAULT NULL,
            created_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
            PRIMARY KEY (id),
            KEY visitor_id (visitor_id),
            KEY campaign_id (campaign_id),
            KEY created_at (created_at)
        ) {$charset_collate};";
	}



	/**
	 * Get settings table SQL
	 *
	 * @param string $charset_collate
	 * @return string
	 */
	private function get_settings_table_sql(string $charset_collate): string
	{
		return "CREATE TABLE IF NOT EXISTS {$this->tables['settings']} (
            id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
            option_key VARCHAR(255) NOT NULL,
            option_value LONGTEXT,
            created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
            updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
            PRIMARY KEY (id),
            UNIQUE KEY option_key (option_key)
        ) {$charset_collate};";
	}

	/**
	 * Get integrations table SQL
	 *
	 * @param string $charset_collate
	 * @return string
	 */
	private function get_integrations_table_sql(string $charset_collate): string
	{
		return "CREATE TABLE IF NOT EXISTS {$this->tables['integrations']} (
            id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
            name VARCHAR(100) NOT NULL,
            title VARCHAR(255) DEFAULT NULL,
            config JSON DEFAULT NULL,
            is_enabled TINYINT(1) DEFAULT 1,
            created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
            updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
            PRIMARY KEY (id),
            UNIQUE KEY name_unique (name)
        ) {$charset_collate};";
	}



	/**
	 * Insert default data into tables
	 *
	 * @return void
	 */
	private function insert_default_data(): void
	{
		$this->insert_default_settings();
		$this->insert_default_categories();
	}

	/**
	 * Insert default settings
	 *
	 * @return void
	 */
	private function insert_default_settings(): void
	{
		global $wpdb;

		// Check if settings already exist
		$existing = $wpdb->get_var($wpdb->prepare(
			"SELECT option_value FROM %i WHERE option_key = %s",
			$this->tables['settings'],
			'general'
		));

		if ($existing) {
			return;
		}
		$default_settings = [
			'customPrefix'           => 'go',
			'disablePrefixByDefault' => true,
			'caseSensitiveRedirects' => false,
			'globalNoFollow'         => false,
			'globalSponsored'        => false,
			'globalRedirectType'     => '302',
		];

		$wpdb->insert(
			$this->tables['settings'],
			[
				'option_key'   => 'general',
				'option_value' => wp_json_encode($default_settings),
				'created_at'   => current_time('mysql'),
				'updated_at'   => current_time('mysql')
			],
			['%s', '%s', '%s', '%s']
		);
	}

	/**
	 * Insert default categories
	 *
	 * @return void
	 */
	private function insert_default_categories(): void
	{
		global $wpdb;

		// Check if categories already exist
		$count = $wpdb->get_var($wpdb->prepare("SELECT COUNT(*) FROM %i", $this->tables['categories']));

		if ($count > 0) {
			return;
		}

		$default_categories = [
			['name' => 'General', 'slug' => 'general', 'description' => 'General campaigns', 'sort_order' => 1],
		];

		foreach ($default_categories as $category) {
			$wpdb->insert(
				$this->tables['categories'],
				array_merge($category, [
					'created_at' => current_time('mysql'),
					'updated_at' => current_time('mysql')
				]),
				['%s', '%s', '%s', '%d', '%s', '%s']
			);
		}
	}
}
