package com.hpay.hpay_mobile_api.controllers;
import com.google.zxing.WriterException;
import com.hpay.hpay_mobile_api.services.CompteService;
import com.hpay.hpay_mobile_api.services.S3Service;
import io.swagger.v3.oas.annotations.Operation;
import com.hpay.hpay_mobile_api.DTO.*;
import com.hpay.hpay_mobile_api.services.AuthService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

@SuppressWarnings("ALL")
@RestController
@RequestMapping("/api/auth")
public class AuthController {

    @Autowired
    private AuthService authService;

    @Autowired
    private S3Service s3Service;

    @Autowired
    private CompteService compteService;

    @Value("${client.photo.upload-dir}")
    private String uploadDir; // The directory to store photos


    // Signup endpoint (Accepts request parameters in the body)
    @Operation(
            summary = "Retourne un message de bienvenue",
            description = "Renvoie un message de bienvenue en français."
    )


    @PostMapping("/signup")
    public ResponseEntity<Object> signup(@RequestBody LoginRequest loginRequest) throws IOException, WriterException {
        Object response = authService.signup(loginRequest);
        if (response instanceof SuccessResponse) {
            return ResponseEntity.status(201).body(response);  // User created successfully
        } else if (response instanceof ErrorResponse) {
            ErrorResponse errorResponse = (ErrorResponse) response;
            return ResponseEntity.status(errorResponse.getStatusCode()).body(errorResponse);  // Error response
        }
        return ResponseEntity.status(400).body(new ErrorResponse("Unknown error", 400)); // Default error response
    }



    // Sign-in endpoint (Accepts request parameters in the body)
    @PostMapping("/signin")
    public ResponseEntity<Object> signin(@RequestBody LoginRequest loginRequest) throws IOException, WriterException {
        Object response = authService.signin(loginRequest.getLogin(), loginRequest.getPassword());
        if (response instanceof SuccessResponse) {
            return ResponseEntity.status(200).body(response);  // Return success response with user data
        } else if (response instanceof ErrorResponse) {
            ErrorResponse errorResponse = (ErrorResponse) response;
            return ResponseEntity.status(errorResponse.getStatusCode()).body(errorResponse);  // Return error response
        }

        return ResponseEntity.status(400).body(new ErrorResponse("Unknown error", 400)); // Default error response
    }




    // API endpoint to validate the LoginClient activation using POST request with JSON body
    @PostMapping("/validate")
    public ResponseEntity<Object> validateLoginClient(@RequestBody LoginClientValidationRequest request) {

        Object response = authService.validateLoginClient(request.getIdLoginClient(), request.getActivationCode());

        if (response instanceof SuccessResponse) {
            return ResponseEntity.status(200).body(response);  // Return success response with user data
        } else if (response instanceof ErrorResponse) {
            ErrorResponse errorResponse = (ErrorResponse) response;
            return ResponseEntity.status(errorResponse.getStatusCode()).body(errorResponse);  // Return error response
        }

        return ResponseEntity.status(400).body(new ErrorResponse("Unknown error", 400)); // Default error response

    }


    @PostMapping("/updateActivationCode/{idLoginClient}")
    public ResponseEntity<Object> updateActivationCode(@PathVariable Long idLoginClient) {

        // Call the service to update the LoginClient's activation code
        Object response = authService.updateActivationCode(idLoginClient);

        if (response instanceof SuccessResponse) {
            return ResponseEntity.status(200).body(response);  // Return success response with user data
        } else if (response instanceof ErrorResponse) {
            ErrorResponse errorResponse = (ErrorResponse) response;
            return ResponseEntity.status(errorResponse.getStatusCode()).body(errorResponse);  // Return error response
        }

        return ResponseEntity.status(400).body(new ErrorResponse("Unknown error", 400)); // Default error response

    }


    // Update client with the given ID and request parameters (nom, prenoms, date_naissance, lieu_naissance)
    @PostMapping("/infoClient/{idClient}")
    public ResponseEntity<Object> updateClient(
            @PathVariable Long idClient, // Get idClient from path
            @RequestBody InfoClientDTO clientUpdateRequest) throws ParseException { // Use the request body DTO


            // Convert the date string into a Date object
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
            Date parsedDate =  dateFormat.parse(clientUpdateRequest.getDateNaissance());

            // Call the service to update the client
            Object response  = authService.updateClientInfo(
                    idClient,
                    clientUpdateRequest.getNom(),
                    clientUpdateRequest.getPrenoms(),
                    clientUpdateRequest.getSex(),
                    parsedDate,
                    clientUpdateRequest.getLieuNaissance()
            );


            if (response instanceof SuccessResponse) {
                return ResponseEntity.status(200).body(response);  // Return success response with user data
            } else if (response instanceof ErrorResponse) {
                ErrorResponse errorResponse = (ErrorResponse) response;
                return ResponseEntity.status(errorResponse.getStatusCode()).body(errorResponse);  // Return error response
            }

            return ResponseEntity.status(400).body(new ErrorResponse("Unknown error", 400)); // Default error response

    }



    @PostMapping("/2faemail/{idClient}/{email}")
    public Object updateEmail(  @PathVariable Long idClient, @PathVariable String email) {

        Object response  = authService.updateEmail(
                idClient,
                email
        );

        if (response instanceof SuccessResponse) {
            return ResponseEntity.status(200).body(response);  // Return success response with user data
        } else if (response instanceof ErrorResponse) {
            ErrorResponse errorResponse = (ErrorResponse) response;
            return ResponseEntity.status(errorResponse.getStatusCode()).body(errorResponse);  // Return error response
        }

        return ResponseEntity.status(400).body(new ErrorResponse("Unknown error", 400)); // Default error response
    }



    // Endpoint to upload a photo for a client
    @PostMapping("/upload-photo/{clientId}")
    public Object uploadClientPhoto(
            @PathVariable Long clientId,
            @RequestParam("photo") MultipartFile photo) throws IOException, ParseException {

        Object response = authService.uploadClientPhoto(clientId, photo);

        if (response instanceof SuccessResponse) {
            return ResponseEntity.status(200).body(response);  // Return success response with user data
        } else if (response instanceof ErrorResponse) {
            ErrorResponse errorResponse = (ErrorResponse) response;
            return ResponseEntity.status(errorResponse.getStatusCode()).body(errorResponse);  // Return error response
        }

        return ResponseEntity.status(400).body(new ErrorResponse("Unknown error", 400));
        
    }


    // Endpoint to get the photo by filename
    @GetMapping("photos/{filename}")
    public ResponseEntity<FileSystemResource> getPhoto(@PathVariable String filename) {

        System.out.println("iccciiii");
        System.out.println(filename);
        // Path to the directory where photos are stored
        //final String UPLOAD_DIR = "C:\\Users\\Personnel\\IdeaProjects\\hpay_mobile_api\\files";

        // Define the file path
        File file = new File(uploadDir+ "\\" + filename);

        if (file.exists()) {
            // Get the file extension
            String fileExtension = getFileExtension(file);
            System.out.println("existe");
            // Set content type based on file extension
            String contentType = "application/octet-stream";  // Default binary stream type
            if (fileExtension.equals("jpg") || fileExtension.equals("jpeg")) {
                contentType = "image/jpeg";
            } else if (fileExtension.equals("png")) {
                contentType = "image/png";
            } else if (fileExtension.equals("gif")) {
                contentType = "image/gif";
            }

            // Set the Content-Type header
            HttpHeaders headers = new HttpHeaders();
            headers.add(HttpHeaders.CONTENT_TYPE, contentType);

            // Return the file as a resource with the correct content type
            return new ResponseEntity<>(new FileSystemResource(file), headers, HttpStatus.OK);
        } else {
            // If the file doesn't exist, return a 404 error
            System.out.println("existe pas");
            return ResponseEntity.notFound().build();
        }

    }



    @GetMapping("client/{id}")
    public Object getClientById(@PathVariable long id) {

        Object response = authService.fetchClient(id);

        if (response instanceof SuccessResponse) {
            return ResponseEntity.status(200).body(response);  // Return success response with user data
        } else if (response instanceof ErrorResponse) {
            ErrorResponse errorResponse = (ErrorResponse) response;
            return ResponseEntity.status(errorResponse.getStatusCode()).body(errorResponse);  // Return error response
        }

        return ResponseEntity.status(400).body(new ErrorResponse("Unknown error", 400));

    }


    @DeleteMapping("/{id}")
    public Object deleteClient(@PathVariable Long id) {

        Object response = authService.deleteLoginClient(id);

        if (response instanceof SuccessResponse) {
            return ResponseEntity.status(200).body(response);  // Return success response with user data
        } else if (response instanceof ErrorResponse) {
            ErrorResponse errorResponse = (ErrorResponse) response;
            return ResponseEntity.status(errorResponse.getStatusCode()).body(errorResponse);  // Return error response
        }

        return ResponseEntity.status(400).body(new ErrorResponse("Unknown error", 400));
    }



    @PostMapping("/validate/email")
    public ResponseEntity<Object> validateEmailClient(@RequestBody LoginClientValidationRequest request) {

        Object response = authService.validateEmailClient(request.getIdLoginClient(), request.getActivationCode());

        if (response instanceof SuccessResponse) {
            return ResponseEntity.status(200).body(response);  // Return success response with user data
        } else if (response instanceof ErrorResponse) {
            ErrorResponse errorResponse = (ErrorResponse) response;
            return ResponseEntity.status(errorResponse.getStatusCode()).body(errorResponse);  // Return error response
        }

        return ResponseEntity.status(400).body(new ErrorResponse("Unknown error", 400)); // Default error response

    }


    // request code for password recover
    @GetMapping("passwordforgot/requestcode/{userName}")
    public Object getClientById(@PathVariable String userName) {

        Object response = authService.passwordforgetRequest(userName);

        if (response instanceof SuccessResponse) {
            return ResponseEntity.status(200).body(response);  // Return success response with user data
        } else if (response instanceof ErrorResponse) {
            ErrorResponse errorResponse = (ErrorResponse) response;
            return ResponseEntity.status(errorResponse.getStatusCode()).body(errorResponse);  // Return error response
        }

        return ResponseEntity.status(400).body(new ErrorResponse("Unknown error", 400));

    }


    @GetMapping("passwordforgot/validatecode/{phone}/{code}")
    public Object requestPasswordForget(@PathVariable String phone, @PathVariable String code) {

        Object response = authService.validatePasswordForgotCode(phone, code);

        if (response instanceof SuccessResponse) {
            return ResponseEntity.status(200).body(response);  // Return success response with user data
        } else if (response instanceof ErrorResponse) {
            ErrorResponse errorResponse = (ErrorResponse) response;
            return ResponseEntity.status(errorResponse.getStatusCode()).body(errorResponse);  // Return error response
        }

        return ResponseEntity.status(400).body(new ErrorResponse("Unknown error", 400));

    }



    @GetMapping("passwordforgot/update/{phone}/{password}")
    public Object updatePasswordForget(@PathVariable String phone, @PathVariable String password) {

        Object response = authService.changepassword(phone, password);

        if (response instanceof SuccessResponse) {
            return ResponseEntity.status(200).body(response);  // Return success response with user data
        } else if (response instanceof ErrorResponse) {
            ErrorResponse errorResponse = (ErrorResponse) response;
            return ResponseEntity.status(errorResponse.getStatusCode()).body(errorResponse);  // Return error response
        }

        return ResponseEntity.status(400).body(new ErrorResponse("Unknown error", 400));

    }


    @PostMapping("/passwordchange")
    public ResponseEntity<Object> changePassword(@RequestBody PasswordChangeRequest request) {

        Object response = authService.changePasswordWithOldPassword(request.getId(), request.getOldpassword(), request.getNewpassword());

        if (response instanceof SuccessResponse) {
            return ResponseEntity.status(200).body(response);  // Return success response with user data
        } else if (response instanceof ErrorResponse) {
            ErrorResponse errorResponse = (ErrorResponse) response;
            return ResponseEntity.status(errorResponse.getStatusCode()).body(errorResponse);  // Return error response
        }

        return ResponseEntity.status(400).body(new ErrorResponse("Unknown error", 400)); // Default error response

    }


    @GetMapping("client/search/{phone}")
    public Object getClientByPhone(@PathVariable String phone) {

        Object response = authService.fetchClientByPhone(phone);

        if (response instanceof SuccessResponse) {
            return ResponseEntity.status(200).body(response);  // Return success response with user data
        } else if (response instanceof ErrorResponse) {
            ErrorResponse errorResponse = (ErrorResponse) response;
            return ResponseEntity.status(errorResponse.getStatusCode()).body(errorResponse);  // Return error response
        }

        return ResponseEntity.status(400).body(new ErrorResponse("Unknown error", 400));

    }


    @PostMapping("addparrainage/{phoneparainee}/{phoneparain}")
    public Object addParrairage(@PathVariable String phoneparainee,@PathVariable String phoneparain) {

        Object response = authService.addParrainage(phoneparainee, phoneparain);

        if (response instanceof SuccessResponse) {
            return ResponseEntity.status(200).body(response);  // Return success response with user data
        } else if (response instanceof ErrorResponse) {
            ErrorResponse errorResponse = (ErrorResponse) response;
            return ResponseEntity.status(errorResponse.getStatusCode()).body(errorResponse);  // Return error response
        }

        return ResponseEntity.status(400).body(new ErrorResponse("Unknown error", 400));

    }


    // Endpoint pour télécharger une image
    @PostMapping("images/charger")
    public ResponseEntity<String> uploadImage(@RequestParam("file") MultipartFile file) {
        //System.out.println("hellllo");
        try {
            String message = s3Service.uploadImage(file);
            return ResponseEntity.ok(message);
        } catch (Exception e) {
            return ResponseEntity.status(500).body("Erreur lors du téléchargement : " + e.getMessage());
        }
    }



    private String getFileExtension(File file) {
        String name = file.getName();
        String extension = "";
        int i = name.lastIndexOf('.');
        if (i > 0) {
            extension = name.substring(i + 1);
        }
        return extension.toLowerCase();
    }


    @GetMapping("client/parrain/{code}")
    public Object getClientByCodeParrainage(@PathVariable String code) {

        Object response = authService.fetchClientByCodeParrainage(code);

        if (response instanceof SuccessResponse) {
            return ResponseEntity.status(200).body(response);  // Return success response with user data
        } else if (response instanceof ErrorResponse) {
            ErrorResponse errorResponse = (ErrorResponse) response;
            return ResponseEntity.status(errorResponse.getStatusCode()).body(errorResponse);  // Return error response
        }

        return ResponseEntity.status(400).body(new ErrorResponse("Unknown error", 400));

    }


    @PostMapping("/generate")
    public String generateQRCode(@RequestParam String text, @RequestParam String fileName) {
        try {
            return s3Service.generateQRCodeAndUploadToS3(text, fileName);
        } catch (Exception e) {
            e.printStackTrace();
            return "Error generating QR code: " + e.getMessage();
        }
    }

    @PostMapping("/sendEmail/valider")
    public ResponseEntity<Object> sendEmailValiderClient(@RequestBody LoginClientValidationRequest request) {

        Object response = authService.sendEmailValiderClient(request.getIdLoginClient());

        if (response instanceof SuccessResponse) {
            return ResponseEntity.status(200).body(response);  // Return success response with user data
        } else if (response instanceof ErrorResponse) {
            ErrorResponse errorResponse = (ErrorResponse) response;
            return ResponseEntity.status(errorResponse.getStatusCode()).body(errorResponse);  // Return error response
        }

        return ResponseEntity.status(400).body(new ErrorResponse("Unknown error", 400)); // Default error response

    }

    @PostMapping("/sendEmail/confirm/account")
    public ResponseEntity<Object> AccountCreatedConfirm(@RequestBody LoginClientValidationRequest request) {

        Object response = authService.accountCreatedConfirm(request.getIdLoginClient());

        if (response instanceof SuccessResponse) {
            return ResponseEntity.status(200).body(response);  // Return success response with user data
        } else if (response instanceof ErrorResponse) {
            ErrorResponse errorResponse = (ErrorResponse) response;
            return ResponseEntity.status(errorResponse.getStatusCode()).body(errorResponse);  // Return error response
        }

        return ResponseEntity.status(400).body(new ErrorResponse("Unknown error", 400)); // Default error response

    }

    @GetMapping("/generate-num")
    public ResponseEntity<String> generateNumCompte() {
        String numCompte = compteService.generateUniqueNumCompte();
        return ResponseEntity.ok(numCompte);
    }



}

