package database

import (
	"context"
	"fmt"
)

// migrateCore creates the core tables: users, auth tokens, sessions,
// documents, versions, consents, cookies, audit, notifications,
// deadlines, suspensions, and their indexes (Phases 1-5).
func migrateCore(db *DB) error {
	ctx := context.Background()

	migrations := []string{
		// Users table (extended for full auth)
		`CREATE TABLE IF NOT EXISTS users (
			id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
			external_id VARCHAR(255) UNIQUE,
			email VARCHAR(255) UNIQUE NOT NULL,
			password_hash VARCHAR(255),
			name VARCHAR(255),
			role VARCHAR(50) DEFAULT 'user',
			email_verified BOOLEAN DEFAULT FALSE,
			email_verified_at TIMESTAMPTZ,
			account_status VARCHAR(20) DEFAULT 'active',
			last_login_at TIMESTAMPTZ,
			failed_login_attempts INT DEFAULT 0,
			locked_until TIMESTAMPTZ,
			created_at TIMESTAMPTZ DEFAULT NOW(),
			updated_at TIMESTAMPTZ DEFAULT NOW()
		)`,

		// Legal documents table
		`CREATE TABLE IF NOT EXISTS legal_documents (
			id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
			type VARCHAR(50) NOT NULL,
			name VARCHAR(255) NOT NULL,
			description TEXT,
			is_mandatory BOOLEAN DEFAULT true,
			is_active BOOLEAN DEFAULT true,
			sort_order INT DEFAULT 0,
			created_at TIMESTAMPTZ DEFAULT NOW(),
			updated_at TIMESTAMPTZ DEFAULT NOW()
		)`,

		// Document versions table
		`CREATE TABLE IF NOT EXISTS document_versions (
			id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
			document_id UUID REFERENCES legal_documents(id) ON DELETE CASCADE,
			version VARCHAR(20) NOT NULL,
			language VARCHAR(5) DEFAULT 'de',
			title VARCHAR(255) NOT NULL,
			content TEXT NOT NULL,
			summary TEXT,
			status VARCHAR(20) DEFAULT 'draft',
			published_at TIMESTAMPTZ,
			scheduled_publish_at TIMESTAMPTZ,
			created_by UUID REFERENCES users(id),
			approved_by UUID REFERENCES users(id),
			approved_at TIMESTAMPTZ,
			created_at TIMESTAMPTZ DEFAULT NOW(),
			updated_at TIMESTAMPTZ DEFAULT NOW(),
			UNIQUE(document_id, version, language)
		)`,

		// Add scheduled_publish_at column if not exists (migration)
		`ALTER TABLE document_versions ADD COLUMN IF NOT EXISTS scheduled_publish_at TIMESTAMPTZ`,
		`ALTER TABLE document_versions ADD COLUMN IF NOT EXISTS approved_at TIMESTAMPTZ`,

		// User consents table
		`CREATE TABLE IF NOT EXISTS user_consents (
			id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
			user_id UUID REFERENCES users(id) ON DELETE CASCADE,
			document_version_id UUID REFERENCES document_versions(id),
			consented BOOLEAN NOT NULL,
			ip_address INET,
			user_agent TEXT,
			consented_at TIMESTAMPTZ DEFAULT NOW(),
			withdrawn_at TIMESTAMPTZ,
			UNIQUE(user_id, document_version_id)
		)`,

		// Cookie categories table
		`CREATE TABLE IF NOT EXISTS cookie_categories (
			id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
			name VARCHAR(100) NOT NULL UNIQUE,
			display_name_de VARCHAR(255) NOT NULL,
			display_name_en VARCHAR(255),
			description_de TEXT,
			description_en TEXT,
			is_mandatory BOOLEAN DEFAULT false,
			sort_order INT DEFAULT 0,
			is_active BOOLEAN DEFAULT true,
			created_at TIMESTAMPTZ DEFAULT NOW(),
			updated_at TIMESTAMPTZ DEFAULT NOW()
		)`,

		// Cookie consents table
		`CREATE TABLE IF NOT EXISTS cookie_consents (
			id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
			user_id UUID REFERENCES users(id) ON DELETE CASCADE,
			category_id UUID REFERENCES cookie_categories(id) ON DELETE CASCADE,
			consented BOOLEAN NOT NULL,
			consented_at TIMESTAMPTZ DEFAULT NOW(),
			updated_at TIMESTAMPTZ DEFAULT NOW(),
			UNIQUE(user_id, category_id)
		)`,

		// Audit log table
		`CREATE TABLE IF NOT EXISTS consent_audit_log (
			id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
			user_id UUID REFERENCES users(id) ON DELETE SET NULL,
			action VARCHAR(50) NOT NULL,
			entity_type VARCHAR(50),
			entity_id UUID,
			details JSONB,
			ip_address INET,
			user_agent TEXT,
			created_at TIMESTAMPTZ DEFAULT NOW()
		)`,

		// Data export requests table
		`CREATE TABLE IF NOT EXISTS data_export_requests (
			id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
			user_id UUID REFERENCES users(id) ON DELETE CASCADE,
			status VARCHAR(20) DEFAULT 'pending',
			download_url TEXT,
			expires_at TIMESTAMPTZ,
			created_at TIMESTAMPTZ DEFAULT NOW(),
			completed_at TIMESTAMPTZ
		)`,

		// Data deletion requests table
		`CREATE TABLE IF NOT EXISTS data_deletion_requests (
			id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
			user_id UUID REFERENCES users(id) ON DELETE CASCADE,
			status VARCHAR(20) DEFAULT 'pending',
			reason TEXT,
			created_at TIMESTAMPTZ DEFAULT NOW(),
			processed_at TIMESTAMPTZ,
			processed_by UUID REFERENCES users(id)
		)`,

		// =============================================
		// Phase 1: User Management Tables
		// =============================================

		// Email verification tokens
		`CREATE TABLE IF NOT EXISTS email_verification_tokens (
			id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
			user_id UUID REFERENCES users(id) ON DELETE CASCADE,
			token VARCHAR(255) UNIQUE NOT NULL,
			expires_at TIMESTAMPTZ NOT NULL,
			used_at TIMESTAMPTZ,
			created_at TIMESTAMPTZ DEFAULT NOW()
		)`,

		// Password reset tokens
		`CREATE TABLE IF NOT EXISTS password_reset_tokens (
			id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
			user_id UUID REFERENCES users(id) ON DELETE CASCADE,
			token VARCHAR(255) UNIQUE NOT NULL,
			expires_at TIMESTAMPTZ NOT NULL,
			used_at TIMESTAMPTZ,
			ip_address INET,
			created_at TIMESTAMPTZ DEFAULT NOW()
		)`,

		// User sessions (for JWT revocation and session management)
		`CREATE TABLE IF NOT EXISTS user_sessions (
			id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
			user_id UUID REFERENCES users(id) ON DELETE CASCADE,
			token_hash VARCHAR(255) NOT NULL,
			device_info TEXT,
			ip_address INET,
			user_agent TEXT,
			expires_at TIMESTAMPTZ NOT NULL,
			revoked_at TIMESTAMPTZ,
			created_at TIMESTAMPTZ DEFAULT NOW(),
			last_activity_at TIMESTAMPTZ DEFAULT NOW()
		)`,

		// =============================================
		// Phase 3: Version Approvals (DSB Workflow)
		// =============================================

		// Version approval tracking
		`CREATE TABLE IF NOT EXISTS version_approvals (
			id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
			version_id UUID REFERENCES document_versions(id) ON DELETE CASCADE,
			approver_id UUID REFERENCES users(id),
			action VARCHAR(30) NOT NULL,
			comment TEXT,
			created_at TIMESTAMPTZ DEFAULT NOW()
		)`,

		// =============================================
		// Phase 4: Notification System
		// =============================================

		// Notifications
		`CREATE TABLE IF NOT EXISTS notifications (
			id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
			user_id UUID REFERENCES users(id) ON DELETE CASCADE,
			type VARCHAR(50) NOT NULL,
			channel VARCHAR(20) NOT NULL,
			title VARCHAR(255) NOT NULL,
			body TEXT NOT NULL,
			data JSONB,
			read_at TIMESTAMPTZ,
			sent_at TIMESTAMPTZ,
			created_at TIMESTAMPTZ DEFAULT NOW()
		)`,

		// Push subscriptions for Web Push
		`CREATE TABLE IF NOT EXISTS push_subscriptions (
			id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
			user_id UUID REFERENCES users(id) ON DELETE CASCADE,
			endpoint TEXT NOT NULL,
			p256dh TEXT NOT NULL,
			auth TEXT NOT NULL,
			user_agent TEXT,
			created_at TIMESTAMPTZ DEFAULT NOW(),
			UNIQUE(user_id, endpoint)
		)`,

		// Notification preferences per user
		`CREATE TABLE IF NOT EXISTS notification_preferences (
			id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
			user_id UUID REFERENCES users(id) ON DELETE CASCADE UNIQUE,
			email_enabled BOOLEAN DEFAULT TRUE,
			push_enabled BOOLEAN DEFAULT TRUE,
			in_app_enabled BOOLEAN DEFAULT TRUE,
			reminder_frequency VARCHAR(20) DEFAULT 'weekly',
			created_at TIMESTAMPTZ DEFAULT NOW(),
			updated_at TIMESTAMPTZ DEFAULT NOW()
		)`,

		// =============================================
		// Phase 5: Consent Deadlines & Account Suspension
		// =============================================

		// Consent deadlines per user per version
		`CREATE TABLE IF NOT EXISTS consent_deadlines (
			id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
			user_id UUID REFERENCES users(id) ON DELETE CASCADE,
			document_version_id UUID REFERENCES document_versions(id) ON DELETE CASCADE,
			deadline_at TIMESTAMPTZ NOT NULL,
			reminder_count INT DEFAULT 0,
			last_reminder_at TIMESTAMPTZ,
			consent_given_at TIMESTAMPTZ,
			created_at TIMESTAMPTZ DEFAULT NOW(),
			UNIQUE(user_id, document_version_id)
		)`,

		// Account suspensions tracking
		`CREATE TABLE IF NOT EXISTS account_suspensions (
			id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
			user_id UUID REFERENCES users(id) ON DELETE CASCADE,
			reason VARCHAR(50) NOT NULL,
			details JSONB,
			suspended_at TIMESTAMPTZ DEFAULT NOW(),
			lifted_at TIMESTAMPTZ,
			lifted_reason TEXT
		)`,

		// =============================================
		// Indexes for performance
		// =============================================
		`CREATE INDEX IF NOT EXISTS idx_user_consents_user ON user_consents(user_id)`,
		`CREATE INDEX IF NOT EXISTS idx_user_consents_version ON user_consents(document_version_id)`,
		`CREATE INDEX IF NOT EXISTS idx_cookie_consents_user ON cookie_consents(user_id)`,
		`CREATE INDEX IF NOT EXISTS idx_audit_log_user ON consent_audit_log(user_id)`,
		`CREATE INDEX IF NOT EXISTS idx_audit_log_created ON consent_audit_log(created_at)`,
		`CREATE INDEX IF NOT EXISTS idx_document_versions_document ON document_versions(document_id)`,
		`CREATE INDEX IF NOT EXISTS idx_document_versions_status ON document_versions(status)`,
		`CREATE INDEX IF NOT EXISTS idx_legal_documents_type ON legal_documents(type)`,

		// Phase 1: Auth indexes
		`CREATE INDEX IF NOT EXISTS idx_email_verification_tokens_token ON email_verification_tokens(token)`,
		`CREATE INDEX IF NOT EXISTS idx_email_verification_tokens_user ON email_verification_tokens(user_id)`,
		`CREATE INDEX IF NOT EXISTS idx_password_reset_tokens_token ON password_reset_tokens(token)`,
		`CREATE INDEX IF NOT EXISTS idx_user_sessions_user ON user_sessions(user_id)`,
		`CREATE INDEX IF NOT EXISTS idx_user_sessions_token ON user_sessions(token_hash)`,

		// Phase 3: Approval indexes
		`CREATE INDEX IF NOT EXISTS idx_version_approvals_version ON version_approvals(version_id)`,

		// Phase 4: Notification indexes
		`CREATE INDEX IF NOT EXISTS idx_notifications_user ON notifications(user_id)`,
		`CREATE INDEX IF NOT EXISTS idx_notifications_unread ON notifications(user_id, read_at)`,
		`CREATE INDEX IF NOT EXISTS idx_push_subscriptions_user ON push_subscriptions(user_id)`,

		// Phase 5: Deadline indexes
		`CREATE INDEX IF NOT EXISTS idx_consent_deadlines_user ON consent_deadlines(user_id)`,
		`CREATE INDEX IF NOT EXISTS idx_consent_deadlines_deadline ON consent_deadlines(deadline_at)`,
		`CREATE INDEX IF NOT EXISTS idx_account_suspensions_user ON account_suspensions(user_id)`,
	}

	for _, migration := range migrations {
		if _, err := db.Pool.Exec(ctx, migration); err != nil {
			return fmt.Errorf("migrateCore: %w", err)
		}
	}

	return nil
}
