package com.platform2easy.genesis.web.controller;

import com.platform2easy.genesis.domain.model.AppUser;
import com.platform2easy.genesis.domain.repository.AppUserRepository;
import com.platform2easy.genesis.domain.service.UserService;
import com.platform2easy.genesis.infra.security.TokenService;
import com.platform2easy.genesis.web.dto.AuthenticationDTO;
import com.platform2easy.genesis.web.dto.RegisterDTO;
import com.platform2easy.genesis.web.dto.TokenDTO;
import jakarta.validation.Valid;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Optional;

@RestController("webAuthenticationController")
@RequestMapping("/auth")
public class AuthenticationController {

    private final UserService service;
    private final AppUserRepository appUserRepository;
    private final PasswordEncoder passwordEncoder;
    private final TokenService tokenService;

    public AuthenticationController(UserService service, AppUserRepository appUserRepository, PasswordEncoder passwordEncoder, TokenService tokenService) {
        this.service = service;
        this.appUserRepository = appUserRepository;
        this.passwordEncoder = passwordEncoder;
        this.tokenService = tokenService;
    }

    @PostMapping("/register")
    public ResponseEntity<?> register(@Valid @RequestBody RegisterDTO dto) {
        Optional<AppUser> existing = appUserRepository.findByUserEmail(dto.getEmail());
        if (existing.isPresent()) {
            return ResponseEntity.status(HttpStatus.CONFLICT).build();
        }
        AppUser user = new AppUser();
        user.setUserName(dto.getName());
        user.setUserEmail(dto.getEmail());
        user.setUserPassword(passwordEncoder.encode(dto.getPassword()));
        user.setUserPhone(dto.getPhone());
        user.setUserAddress(dto.getAddress());
        user.setUserCity(dto.getCity());
        user.setUserState(dto.getState());
        user.setUserZip(dto.getZip());
        user.setUserCountry(dto.getCountry());
        user.setUserKyc(dto.getKyc());
        user.setUserBirthdate(dto.getBirthdate());
        user.setUserCpf(dto.getCpf());
        user.setCompanyId(dto.getCompanyId());
        user.setRoleId(dto.getRoleId());
        user.setUserFlag(dto.getFlag());
        AppUser saved = appUserRepository.save(user);
        String token = tokenService.generateToken(saved);
        return ResponseEntity.status(HttpStatus.CREATED).body(new TokenDTO(token, saved.getCompanyId(), saved.getUserId()));
    }

    @PostMapping("/login")
    public ResponseEntity<?> login(@Valid @RequestBody AuthenticationDTO dto) {
        Optional<AppUser> existing = appUserRepository.findByUserEmail(dto.getEmail());
        if (existing.isEmpty()) {
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
        }
        AppUser user = existing.get();
        if (!passwordEncoder.matches(dto.getPassword(), user.getUserPassword())) {
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
        }
        String token = tokenService.generateToken(user);
        return ResponseEntity.ok(new TokenDTO(token, user.getCompanyId(), user.getUserId()));
    }

    @PostMapping("/register/default")
    public ResponseEntity<?> registerDefault() {
        final String email = "tester@tooeasy.local";
        final String rawPassword = "ChangeMe123!";

        Optional<AppUser> existing = appUserRepository.findByUserEmail(email);
        AppUser user;
        HttpStatus status;
        if (existing.isPresent()) {
            user = existing.get();
            status = HttpStatus.OK;
        } else {
            user = new AppUser();
            user.setUserName("Tester");
            user.setUserEmail(email);
            user.setUserPassword(passwordEncoder.encode(rawPassword));
            user.setUserPhone("0000000000");
            user.setUserAddress("N/A");
            user.setUserCity("N/A");
            user.setUserState("NA");
            user.setUserZip("00000");
            user.setUserCountry("BR");
            user.setUserKyc(1);
            user.setUserBirthdate(19900101);
            user.setUserCpf("00000000000");
            user.setCompanyId(1);
            user.setRoleId(1);
            user.setUserFlag("ACTIVE");
            user = appUserRepository.save(user);
            status = HttpStatus.CREATED;
        }
        String token = tokenService.generateToken(user);
        return ResponseEntity.status(status).body(new TokenDTO(token, user.getCompanyId()));
    }

    // GET /auth/company/{companyId}: Lista todos os usuários de uma empresa
    @GetMapping("/company/{companyId}")
        @ResponseStatus(HttpStatus.OK)
        public List<AppUser> getUsersByCompanyId(@PathVariable Integer companyId) {
            return service.buscarPorEmpresa(companyId);
    }

    // PUT /auth/email/{id}: Atualiza apenas o email
    @PutMapping("/email/{id}")
    @ResponseStatus(HttpStatus.OK)
    public AppUser updateEmail(@PathVariable Long id, @RequestBody AppUser userRequest) {
        AppUser user = appUserRepository.findById(id).orElseThrow();
        user.setUserEmail(userRequest.getUserEmail());
        return appUserRepository.save(user);
    }

    // PUT /auth/password/{id}: Atualiza apenas a senha (hash via passwordEncoder)
    @PutMapping("/password/{id}")
    @ResponseStatus(HttpStatus.OK)
    public AppUser updatePassword(@PathVariable Long id, @RequestBody AppUser userRequest) {
        AppUser user = appUserRepository.findById(id).orElseThrow();
        user.setUserPassword(passwordEncoder.encode(userRequest.getUserPassword()));
        return appUserRepository.save(user);
    }

    // DELETE /auth/{id}: Hard delete do usuário
    @DeleteMapping("/{id}")
    @ResponseStatus(HttpStatus.NO_CONTENT)
    public void delete(@PathVariable Long id) {
        service.deletarPorId(id);
    }
    
    @PostMapping("/validate-token")
    public ResponseEntity<TokenDTO> validateToken(@RequestHeader("Authorization") String authHeader) {
        if (authHeader == null || !authHeader.startsWith("Bearer ")) {
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
        }
        
        String token = authHeader.substring(7);
        try {
            // First validate the token
            if (!tokenService.validateToken(token)) {
                return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
            }
            
            // If token is valid, get the username from the token
            String username = tokenService.getSubject(token);
            Optional<AppUser> userOpt = appUserRepository.findByUserEmail(username);
            
            if (userOpt.isEmpty()) {
                return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
            }
            
            AppUser user = userOpt.get();
            return ResponseEntity.ok(new TokenDTO(token, user.getCompanyId(), user.getUserId()));
            
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
        }
    }
}