/**
 * DSGVO Module
 *
 * GDPR compliance functionality
 */

import type {
  DSRRequest,
  DSRRequestType,
  ConsentRecord,
  ConsentPurpose,
  ProcessingActivity,
  DSFA,
  TOM,
  RetentionPolicy,
  CookieBannerConfig,
  SDKState,
} from '@breakpilot/compliance-sdk-types'
import { ComplianceClient } from '../client'

export class DSGVOModule {
  private client: ComplianceClient
  private getState: () => SDKState

  constructor(client: ComplianceClient, getState: () => SDKState) {
    this.client = client
    this.getState = getState
  }

  // ---------------------------------------------------------------------------
  // DSR (Data Subject Requests)
  // ---------------------------------------------------------------------------

  async submitDSR(type: DSRRequestType, requesterEmail: string, requesterName: string): Promise<DSRRequest> {
    const response = await fetch(`${this.client.getTenantId()}/dsgvo/dsr`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ type, requesterEmail, requesterName }),
    })
    return response.json()
  }

  getDSRRequests(): DSRRequest[] {
    return this.getState().dsrRequests
  }

  getDSRById(id: string): DSRRequest | undefined {
    return this.getState().dsrRequests.find(r => r.id === id)
  }

  // ---------------------------------------------------------------------------
  // Consent Management
  // ---------------------------------------------------------------------------

  getConsents(): ConsentRecord[] {
    return this.getState().consents
  }

  getConsentsByUserId(userId: string): ConsentRecord[] {
    return this.getState().consents.filter(c => c.userId === userId)
  }

  hasConsent(userId: string, purpose: ConsentPurpose): boolean {
    const consents = this.getConsentsByUserId(userId)
    const latestConsent = consents
      .filter(c => c.consentType === purpose)
      .sort((a, b) => new Date(b.grantedAt).getTime() - new Date(a.grantedAt).getTime())[0]

    return latestConsent?.granted && !latestConsent.revokedAt
  }

  // ---------------------------------------------------------------------------
  // VVT (Processing Register)
  // ---------------------------------------------------------------------------

  getProcessingActivities(): ProcessingActivity[] {
    return this.getState().vvt
  }

  getProcessingActivityById(id: string): ProcessingActivity | undefined {
    return this.getState().vvt.find(p => p.id === id)
  }

  // ---------------------------------------------------------------------------
  // DSFA
  // ---------------------------------------------------------------------------

  getDSFA(): DSFA | null {
    return this.getState().dsfa
  }

  isDSFARequired(): boolean {
    const state = this.getState()
    const activeUseCase = state.useCases.find(uc => uc.id === state.activeUseCase)
    return activeUseCase?.assessmentResult?.dsfaRequired ?? false
  }

  // ---------------------------------------------------------------------------
  // TOMs
  // ---------------------------------------------------------------------------

  getTOMs(): TOM[] {
    return this.getState().toms
  }

  getTOMsByCategory(category: string): TOM[] {
    return this.getState().toms.filter(t => t.category === category)
  }

  getTOMScore(): number {
    const toms = this.getTOMs()
    if (toms.length === 0) return 0

    const implemented = toms.filter(t => t.implementationStatus === 'IMPLEMENTED').length
    return Math.round((implemented / toms.length) * 100)
  }

  // ---------------------------------------------------------------------------
  // Retention Policies
  // ---------------------------------------------------------------------------

  getRetentionPolicies(): RetentionPolicy[] {
    return this.getState().retentionPolicies
  }

  getUpcomingDeletions(days: number = 30): RetentionPolicy[] {
    const cutoff = new Date()
    cutoff.setDate(cutoff.getDate() + days)

    return this.getState().retentionPolicies.filter(p => {
      const nextReview = new Date(p.nextReviewDate)
      return nextReview <= cutoff
    })
  }

  // ---------------------------------------------------------------------------
  // Cookie Banner
  // ---------------------------------------------------------------------------

  getCookieBannerConfig(): CookieBannerConfig | null {
    return this.getState().cookieBanner
  }

  async generateCookieBannerCode(): Promise<{ html: string; css: string; js: string } | null> {
    const config = this.getCookieBannerConfig()
    if (!config) return null

    const response = await this.client.generateDocument('cookie_banner', { config })
    return response.content ? JSON.parse(response.content) : null
  }
}

export function createDSGVOModule(client: ComplianceClient, getState: () => SDKState): DSGVOModule {
  return new DSGVOModule(client, getState)
}
