<?php

declare(strict_types=1);

namespace OCA\Mitgliederverwaltung\Controller;

use OCA\Mitgliederverwaltung\Service\DsgvoService;
use OCA\Mitgliederverwaltung\Service\EncryptedExportService;
use OCA\Mitgliederverwaltung\Service\PermissionService;
use OCA\Mitgliederverwaltung\Service\ValidationException;
use OCP\AppFramework\ApiController;
use OCP\AppFramework\Db\DoesNotExistException;
use OCP\AppFramework\Http;
use OCP\AppFramework\Http\DataDownloadResponse;
use OCP\AppFramework\Http\JSONResponse;
use OCP\IRequest;
use OCP\IUserSession;
use Psr\Log\LoggerInterface;

/**
 * REST API controller for DSGVO compliance actions.
 *
 * Both endpoints are admin-only and audit-logged.
 *
 * Part of Issue #62.
 */
class DsgvoController extends ApiController {

    use ApiControllerTrait;

    private DsgvoService $dsgvoService;
    private EncryptedExportService $encryptedService;
    private PermissionService $permissionService;
    private IUserSession $userSession;
    private LoggerInterface $logger;

    public function __construct(
        string $appName,
        IRequest $request,
        DsgvoService $dsgvoService,
        EncryptedExportService $encryptedService,
        PermissionService $permissionService,
        IUserSession $userSession,
        LoggerInterface $logger
    ) {
        parent::__construct($appName, $request);
        $this->dsgvoService = $dsgvoService;
        $this->encryptedService = $encryptedService;
        $this->permissionService = $permissionService;
        $this->userSession = $userSession;
        $this->logger = $logger;
    }

    /**
     * Export all data for a member as encrypted JSON (Auskunftsrecht).
     *
     * POST /api/v1/members/{id}/dsgvo-export
     * Body: { "password": "..." }
     */
    public function export(int $id): DataDownloadResponse|JSONResponse {
        try {
            $this->assertAdmin();

            $body = $this->getRequestData();
            $password = $body['password'] ?? null;
            if ($password === null || $password === '') {
                return new JSONResponse(
                    ['error' => 'Passwort ist erforderlich'],
                    Http::STATUS_BAD_REQUEST
                );
            }

            $data = $this->dsgvoService->exportMemberData($id);

            // Convert to formatted JSON
            $jsonContent = json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
            $innerFilename = "DSGVO_Export_Mitglied_{$id}_" . date('Y-m-d') . '.json';

            $zipResult = $this->encryptedService->createEncryptedExport(
                $jsonContent,
                $innerFilename,
                $password,
                'DSGVO-Export'
            );

            return new DataDownloadResponse(
                $zipResult['content'],
                $zipResult['filename'],
                'application/zip'
            );
        } catch (DoesNotExistException $e) {
            return new JSONResponse(
                ['error' => 'Mitglied nicht gefunden'],
                Http::STATUS_NOT_FOUND
            );
        } catch (ValidationException $e) {
            return new JSONResponse(
                ['error' => $e->getMessage()],
                Http::STATUS_FORBIDDEN
            );
        } catch (\Exception $e) {
            $this->logger->error('DSGVO export failed', [
                'memberId' => $id,
                'exception' => $e,
                'app' => 'mitgliederverwaltung',
            ]);
            return new JSONResponse(
                ['error' => 'DSGVO-Export fehlgeschlagen'],
                Http::STATUS_INTERNAL_SERVER_ERROR
            );
        }
    }

    /**
     * Irreversible hard-delete of all member data (Recht auf Loeschung).
     *
     * DELETE /api/v1/members/{id}/dsgvo-delete
     * Body: { "confirm": true }
     */
    public function hardDelete(int $id): JSONResponse {
        try {
            $this->assertAdmin();

            // Double-confirm: require explicit confirmation in request body
            $body = $this->getRequestData();
            $confirm = $body['confirm'] ?? null;
            if ($confirm !== true && $confirm !== 'true' && $confirm !== '1') {
                return new JSONResponse(
                    ['error' => 'Bestaetigung erforderlich: "confirm": true'],
                    Http::STATUS_BAD_REQUEST
                );
            }

            $this->dsgvoService->hardDeleteMember($id);

            return new JSONResponse([
                'status' => 'deleted',
                'message' => 'Alle Daten fuer Mitglied unwiderruflich geloescht (DSGVO Art. 17)',
            ]);
        } catch (DoesNotExistException $e) {
            return new JSONResponse(
                ['error' => 'Mitglied nicht gefunden'],
                Http::STATUS_NOT_FOUND
            );
        } catch (ValidationException $e) {
            return new JSONResponse(
                ['error' => $e->getMessage()],
                Http::STATUS_FORBIDDEN
            );
        } catch (\Exception $e) {
            $this->logger->error('DSGVO hard-delete failed', [
                'memberId' => $id,
                'exception' => $e,
                'app' => 'mitgliederverwaltung',
            ]);
            return new JSONResponse(
                ['error' => 'DSGVO-Loeschung fehlgeschlagen'],
                Http::STATUS_INTERNAL_SERVER_ERROR
            );
        }
    }

    /**
     * Verify the current user is an admin.
     *
     * @throws ValidationException If the user is not an admin
     */
    private function assertAdmin(): void {
        $userId = $this->getCurrentUserId();
        if (!$this->permissionService->isAdmin($userId)) {
            throw new ValidationException(
                'DSGVO-Aktionen sind nur fuer Administratoren verfuegbar.'
            );
        }
    }

    private function getCurrentUserId(): string {
        $user = $this->userSession->getUser();
        return $user ? $user->getUID() : 'system';
    }
}
