package de.oaa.xxx.games.chastity.lockcontroll;

import de.oaa.xxx.games.chastity.common.CodeCreator;
import de.oaa.xxx.games.chastity.ttlock.TTAuthService;
import de.oaa.xxx.games.chastity.ttlock.TTLockConfigEntity;
import de.oaa.xxx.games.chastity.ttlock.TTLockService;
import de.oaa.xxx.games.chastity.ttlock.TTLockUserConfigEntity;
import de.oaa.xxx.games.chastity.ttlock.TTLockUserConfigRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class TTLockControl extends LockControl {

    private static final Logger LOGGER = LoggerFactory.getLogger(TTLockControl.class);

    private final TTAuthService ttAuthService;
    private final TTLockService ttLockService;
    private final TTLockConfigEntity adminConfig;
    private final TTLockUserConfigEntity userConfig;
    private final TTLockUserConfigRepository userConfigRepository;

    public TTLockControl(TTAuthService ttAuthService,
                         TTLockService ttLockService,
                         TTLockConfigEntity adminConfig,
                         TTLockUserConfigEntity userConfig,
                         TTLockUserConfigRepository userConfigRepository,
                         LockControlCallback callback) {
        super(callback);
        this.ttAuthService = ttAuthService;
        this.ttLockService = ttLockService;
        this.adminConfig = adminConfig;
        this.userConfig = userConfig;
        this.userConfigRepository = userConfigRepository;
    }

    @Override
    public boolean init() {
        return true;
    }

    @Override
    public boolean lock() {
        if (!isConfigValid()) {
            LOGGER.warn("TTLock-Konfiguration unvollständig – lock() übersprungen");
            return false;
        }
        try {
            String token = getToken();
            if (token == null) {
                LOGGER.error("TTLock: Kein Access Token erhalten");
                return false;
            }

            // Neuen PIN erstellen – Länge aus Callback, mindestens 4, maximal 9 (TTLock-Limit)
            int pinLength = Math.min(9, Math.max(4, callback.getUnlockcodeLenght()));
            String newPin = CodeCreator.createNumeric(pinLength);
            Integer newPwdId = ttLockService.addCustomPasscode(
                    adminConfig.getClientId(), token,
                    userConfig.getLockId(), newPin);

            if (newPwdId == null) {
                LOGGER.error("TTLock: Neuer PIN konnte nicht erstellt werden – alter PIN bleibt erhalten");
                return false;
            }
            callback.setUnlockCode(newPin);

            // Neuen PIN-ID speichern, dann alten PIN löschen
            Integer oldPwdId = userConfig.getCurrentKeyboardPwdId();
            userConfig.setCurrentKeyboardPwdId(newPwdId);
            userConfigRepository.save(userConfig);
            LOGGER.info("TTLock: Neuer PIN gesetzt (pwdId={})", newPwdId);

            
            if (oldPwdId != null) {
                ttLockService.deleteCustomPasscode(
                        adminConfig.getClientId(), token,
                        userConfig.getLockId(), oldPwdId);
                LOGGER.debug("TTLock: Alter PIN {} gelöscht", oldPwdId);
            }

            return true;
        } catch (Exception e) {
            LOGGER.error("TTLock lock() fehlgeschlagen: {}", e.getMessage(), e);
            return false;
        }
    }

    /**
     * Löscht den aktuellen PIN vom Schloss, sodass es entsperrt bleibt.
     */
    @Override
    public boolean unlock() {
        if (!isConfigValid() || userConfig.getCurrentKeyboardPwdId() == null) {
            return true; // Kein PIN gesetzt – nichts zu tun
        }
        try {
            String token = getToken();
            if (token == null) return false;

            ttLockService.deleteCustomPasscode(
                    adminConfig.getClientId(), token,
                    userConfig.getLockId(), userConfig.getCurrentKeyboardPwdId());

            userConfig.setCurrentKeyboardPwdId(null);
            userConfigRepository.save(userConfig);
            LOGGER.info("TTLock: PIN gelöscht (Entsperrung)");
            return true;
        } catch (Exception e) {
            LOGGER.error("TTLock unlock() fehlgeschlagen: {}", e.getMessage(), e);
            return false;
        }
    }

    private String getToken() {
        return ttAuthService.getAccessToken(
                adminConfig.getClientId(),
                adminConfig.getClientSecret(),
                userConfig.getUsername(),
                userConfig.getPasswordMd5());
    }

    private boolean isConfigValid() {
        return adminConfig != null
                && adminConfig.getClientId() != null
                && adminConfig.getClientSecret() != null
                && userConfig != null
                && userConfig.getUsername() != null
                && userConfig.getPasswordMd5() != null
                && userConfig.getLockId() != null;
    }

	@Override
	public boolean cleanup() {
        String token = getToken();
        if (token == null) {
            LOGGER.error("TTLock: Kein Access Token erhalten");
            return false;
        }
        ttLockService.findAndDeleteLocksByName(adminConfig.getClientId(), token, userConfig.getLockId());
        return true;
	}
}
