package com.toshibabd.customermanagement;

import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.SearchView;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

import com.toshibabd.customermanagement.adapter.CustomerAdapter;
import com.toshibabd.customermanagement.api.ApiService;
import com.toshibabd.customermanagement.api.RetrofitClient;
import com.toshibabd.customermanagement.model.ApiResponse;
import com.toshibabd.customermanagement.model.Customer;
import com.toshibabd.customermanagement.util.Utils;
import com.google.android.material.textfield.TextInputEditText;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

public class MainActivity extends AppCompatActivity implements CustomerAdapter.OnCustomerActionListener {

    private RecyclerView recyclerView;
    private CustomerAdapter customerAdapter;
    private ApiService apiService;
    private SmsSender smsSender;
    private static final String TAG = "MainActivity";
    private static final String DEFAULT_COUNTRY_CODE = "880"; // Bangladesh Country Code

    private TextView emptyView;
    private ActivityResultLauncher<String> filePickerLauncher;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        apiService = RetrofitClient.getApiService();
        smsSender = new SmsSender(); // Initialize SmsSender

        emptyView = findViewById(R.id.text_empty_view);

        filePickerLauncher = registerForActivityResult(new ActivityResultContracts.GetContent(), uri -> {
            if (uri != null) {
                handleCsvFileImport(uri);
            } else {
                Toast.makeText(MainActivity.this, "File selection cancelled.", Toast.LENGTH_SHORT).show();
            }
        });

        setupRecyclerView();

        findViewById(R.id.btn_bulk_wa).setOnClickListener(this::onBulkWaClick);
        findViewById(R.id.btn_manual_wa).setOnClickListener(this::onManualWaClick);
        findViewById(R.id.btn_bulk_sms).setOnClickListener(this::onBulkSmsClick);

        loadCustomers(null);
    }

    // Lifecycle methods are clean as native SMS receivers are removed
    @Override
    protected void onResume() {
        super.onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
    }

    private void setupRecyclerView() {
        recyclerView = findViewById(R.id.recycler_view_customers);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        customerAdapter = new CustomerAdapter(this, this);
        recyclerView.setAdapter(customerAdapter);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main_menu, menu);

        MenuItem searchItem = menu.findItem(R.id.action_search);
        SearchView searchView = (SearchView) searchItem.getActionView();

        searchView.setQueryHint("Search by Name, Mobile, Product, Category, or Note...");

        searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String query) {
                loadCustomers(query);
                return true;
            }

            @Override
            public boolean onQueryTextChange(String newText) {
                if (newText.length() > 2 || newText.isEmpty()) {
                    loadCustomers(newText);
                }
                return true;
            }
        });
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();

        if (id == R.id.action_add_customer) {
            showCustomerDialog(null);
            return true;
        } else if (id == R.id.action_bulk_send) {
            handleBulkSendMessage();
            return true;
        } else if (id == R.id.action_bulk_import) {
            startCsvImportProcess();
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    // ----------------------------------------------------------------------
    // SMS API Execution
    // ----------------------------------------------------------------------

    public void onBulkSmsClick(View view) {
        List<Integer> selectedIds = customerAdapter.getSelectedCustomerIds();

        if (selectedIds.isEmpty()) {
            Toast.makeText(this, "Please select at least one customer to send SMS.", Toast.LENGTH_SHORT).show();
            return;
        }

        // Proceed directly as we use API, not native Android SMS
        showSmsComposeDialog(selectedIds);
    }

    private void showSmsComposeDialog(final List<Integer> selectedIds) {
        View dialogView = LayoutInflater.from(this).inflate(R.layout.dialog_sms_compose, null);

        TextView title = dialogView.findViewById(R.id.dialog_title);
        TextInputEditText editMessage = dialogView.findViewById(R.id.edit_sms_message);
        TextView recipientCount = dialogView.findViewById(R.id.text_recipient_count);

        title.setText("Compose Bulk SMS (API Gateway)");
        recipientCount.setText(selectedIds.size() + " Recipients Selected");

        editMessage.setText("Dear Customer, your update is ready.");

        AlertDialog.Builder builder = new AlertDialog.Builder(this)
                .setView(dialogView)
                .setPositiveButton("Send SMS", null)
                .setNegativeButton("Cancel", (dialog, which) -> {
                    customerAdapter.clearSelectedCustomers();
                });

        final AlertDialog dialog = builder.create();

        dialog.setOnShowListener(dialogInterface -> {
            dialog.getButton(DialogInterface.BUTTON_POSITIVE).setOnClickListener(v -> {
                String message = editMessage.getText().toString().trim();

                if (message.isEmpty()) {
                    Toast.makeText(MainActivity.this, "SMS message cannot be empty.", Toast.LENGTH_SHORT).show();
                    return;
                }

                executeBulkSmsRequest(selectedIds, message, dialog);
            });
        });

        dialog.show();
    }

    private void executeBulkSmsRequest(List<Integer> selectedIds, String message, AlertDialog dialog) {
        customerAdapter.clearSelectedCustomers();
        dialog.dismiss();

        List<Customer> customersToSend = customerAdapter.getCustomers().stream()
                .filter(c -> selectedIds.contains(c.getId()))
                .collect(Collectors.toList());

        if (customersToSend.isEmpty()) {
            Toast.makeText(this, "Error: Could not retrieve customer data.", Toast.LENGTH_SHORT).show();
            return;
        }

        Toast.makeText(this, "Initiating API send for " + customersToSend.size() + " messages...", Toast.LENGTH_LONG).show();

        AtomicInteger successCount = new AtomicInteger(0);
        AtomicInteger failureCount = new AtomicInteger(0);
        int totalCount = customersToSend.size();

        // Run network operation on a separate thread
        new Thread(() -> {
            for (Customer customer : customersToSend) {
                String finalMessage = message.replace("Dear Customer", "Dear " + customer.getName());

                boolean success = smsSender.sendCustomSms(customer, finalMessage);

                if (success) {
                    successCount.incrementAndGet();
                    updateCustomerStatus(customer.getId()); // Update DB status
                } else {
                    failureCount.incrementAndGet();
                    Log.e(TAG, "API failed for customer: " + customer.getName());
                }
            }

            // Post result back to the Main Thread for UI updates
            runOnUiThread(() -> {
                Toast.makeText(MainActivity.this,
                        "Bulk SMS finished. Success: " + successCount.get() +
                                ", Failed: " + failureCount.get() +
                                ", Total: " + totalCount,
                        Toast.LENGTH_LONG).show();

                loadCustomers(null);
            });

        }).start();
    }

    private void updateCustomerStatus(int customerId) {
        String currentDateTime = Utils.getCurrentDateTimeForDb();
        // Status 1 indicates SENT via API/Service
        apiService.updateStatus(customerId, 1, currentDateTime).enqueue(new Callback<ApiResponse>() {
            @Override
            public void onResponse(Call<ApiResponse> call, Response<ApiResponse> response) {
                if (!response.isSuccessful()) {
                    Log.e(TAG, "Failed status update via PHP for ID: " + customerId);
                }
            }
            @Override
            public void onFailure(Call<ApiResponse> call, Throwable t) {
                Log.e(TAG, "Network failure on DB update for ID: " + customerId, t);
            }
        });
    }

    // ----------------------------------------------------------------------
    // WhatsApp Execution (FIXED for Country Code)
    // ----------------------------------------------------------------------

    public void onBulkWaClick(View view) {
        List<Integer> selectedIds = customerAdapter.getSelectedCustomerIds();
        if (selectedIds.isEmpty()) {
            Toast.makeText(this, "No customers selected for Bulk WA.", Toast.LENGTH_SHORT).show();
            return;
        }
        Toast.makeText(this, "Bulk WA initiated for " + selectedIds.size() + " customers (Requires WhatsApp API).", Toast.LENGTH_LONG).show();
        // TODO: Implement API call to bulk_whatsapp.php here
        customerAdapter.clearSelectedCustomers();
        loadCustomers(null);
    }

    public void onManualWaClick(View view) {
        List<Integer> selectedIds = customerAdapter.getSelectedCustomerIds();

        if (selectedIds.size() != 1) {
            Toast.makeText(this, "Please select exactly one customer for Manual WA.", Toast.LENGTH_SHORT).show();
            return;
        }
        Customer selectedCustomer = customerAdapter.getCustomerById(selectedIds.get(0));

        if (selectedCustomer != null) {
            sendWhatsAppIntent(selectedCustomer.getMobileNumber());
            customerAdapter.clearSelectedCustomers();
        } else {
            Toast.makeText(this, "Customer data retrieval error.", Toast.LENGTH_SHORT).show();
        }
    }

    private void sendWhatsAppIntent(String mobileNumber) {
        try {
            // 1. Clean the number: remove +, spaces, and dashes
            String cleanNumber = mobileNumber
                    .replace("+", "")
                    .replaceAll("\\s+", "")
                    .replace("-", "");

            // 2. Adjust for local format (Assuming Bangladesh: +880 is standard)
            String finalNumber;

            // If it starts with '0' (local dialing), remove the '0' and prepend the country code.
            if (cleanNumber.startsWith("0")) {
                cleanNumber = cleanNumber.substring(1);
                finalNumber = DEFAULT_COUNTRY_CODE + cleanNumber;
            }
            // If it doesn't start with 880 and is too short to already have a country code, prepend 880.
            else if (!cleanNumber.startsWith(DEFAULT_COUNTRY_CODE) && cleanNumber.length() < 12) {
                finalNumber = DEFAULT_COUNTRY_CODE + cleanNumber;
            }
            // Otherwise, use the cleaned number (it should already be in international format)
            else {
                finalNumber = cleanNumber;
            }

            String message = "Hello! Here is your status update.";
            // WhatsApp URL requires the international number (880xxxxxxxxxx)
            String url = "https://api.whatsapp.com/send?phone=" + finalNumber + "&text=" + android.net.Uri.encode(message);

            Intent intent = new Intent(Intent.ACTION_VIEW);
            intent.setData(android.net.Uri.parse(url));
            startActivity(intent);

        } catch (Exception e) {
            Toast.makeText(this, "WhatsApp app not installed or invalid number format.", Toast.LENGTH_LONG).show();
            Log.e(TAG, "WhatsApp Intent Failed", e);
        }
    }

    // ----------------------------------------------------------------------
    // CRUD and Utilities (Unchanged)
    // ----------------------------------------------------------------------

    @Override
    public void onCustomerEdit(Customer customer) { showCustomerDialog(customer); }

    private void showCustomerDialog(final Customer customer) {
        View dialogView = LayoutInflater.from(this).inflate(R.layout.dialog_add_edit_customer, null);
        TextView title = dialogView.findViewById(R.id.dialog_title);
        TextInputEditText editName = dialogView.findViewById(R.id.edit_name);
        TextInputEditText editMobile = dialogView.findViewById(R.id.edit_mobile_number);

        TextInputEditText editProduct = dialogView.findViewById(R.id.edit_product_label);
        TextInputEditText editCategory = dialogView.findViewById(R.id.edit_category);

        TextInputEditText editNote = dialogView.findViewById(R.id.edit_customer_note);

        final String[] productOptions = getResources().getStringArray(R.array.product_options);
        final boolean[] productCheckedItems = new boolean[productOptions.length];

        final String[] categoryOptions = getResources().getStringArray(R.array.customer_categories);
        final boolean[] categoryCheckedItems = new boolean[categoryOptions.length];


        final boolean isEdit = (customer != null);
        title.setText(isEdit ? "Edit Customer ID: " + customer.getId() : "Add New Customer");

        if (isEdit) {
            editName.setText(customer.getName());
            editMobile.setText(customer.getMobileNumber());
            editProduct.setText(customer.getProductLabel());
            editCategory.setText(customer.getCategory());

            String currentProducts = customer.getProductLabel() != null ? customer.getProductLabel() : "";
            List<String> currentSelectedProducts = Arrays.asList(currentProducts.split("\\s*,\\s*"));
            for (int i = 0; i < productOptions.length; i++) {
                if (currentSelectedProducts.contains(productOptions[i])) {
                    productCheckedItems[i] = true;
                }
            }

            String currentCategories = customer.getCategory() != null ? customer.getCategory() : "";
            List<String> currentSelectedCategories = Arrays.asList(currentCategories.split("\\s*,\\s*"));
            for (int i = 0; i < categoryOptions.length; i++) {
                if (currentSelectedCategories.contains(categoryOptions[i])) {
                    categoryCheckedItems[i] = true;
                }
            }

            if (customer.getNote() != null) {
                editNote.setText(customer.getNote());
            }
        }

        editProduct.setOnClickListener(v -> {
            new AlertDialog.Builder(MainActivity.this)
                    .setTitle("Select Product Label(s)")
                    .setMultiChoiceItems(productOptions, productCheckedItems, (dialog, which, isChecked) -> {
                        productCheckedItems[which] = isChecked;
                    })
                    .setPositiveButton("OK", (dialog, which) -> {
                        List<String> selectedProducts = new ArrayList<>();
                        for (int i = 0; i < productOptions.length; i++) {
                            if (productCheckedItems[i]) {
                                selectedProducts.add(productOptions[i]);
                            }
                        }
                        String productString = String.join(", ", selectedProducts);
                        editProduct.setText(productString);
                    })
                    .setNegativeButton("Cancel", null)
                    .show();
        });

        editCategory.setOnClickListener(v -> {
            new AlertDialog.Builder(MainActivity.this)
                    .setTitle("Select Customer Type/Category")
                    .setMultiChoiceItems(categoryOptions, categoryCheckedItems, (dialog, which, isChecked) -> {
                        categoryCheckedItems[which] = isChecked;
                    })
                    .setPositiveButton("OK", (dialog, which) -> {
                        List<String> selectedCategories = new ArrayList<>();
                        for (int i = 0; i < categoryOptions.length; i++) {
                            if (categoryCheckedItems[i]) {
                                selectedCategories.add(categoryOptions[i]);
                            }
                        }
                        String categoryString = String.join(", ", selectedCategories);
                        editCategory.setText(categoryString);
                    })
                    .setNegativeButton("Cancel", null)
                    .show();
        });


        AlertDialog.Builder builder = new AlertDialog.Builder(this)
                .setView(dialogView)
                .setPositiveButton(isEdit ? "Update" : "Add", null)
                .setNegativeButton("Cancel", null);

        final AlertDialog dialog = builder.create();

        dialog.setOnShowListener(dialogInterface -> {
            dialog.getButton(DialogInterface.BUTTON_POSITIVE).setOnClickListener(v -> {

                String name = editName.getText().toString().trim();
                String mobile = editMobile.getText().toString().trim();

                String product = editProduct.getText().toString().trim();
                String category = editCategory.getText().toString().trim();

                String note = editNote.getText().toString().trim();

                if (name.isEmpty() || mobile.length() < 10 || product.isEmpty() || category.isEmpty()) {
                    Toast.makeText(MainActivity.this, "Please fill all required fields correctly (Name, Mobile, Product, Category).", Toast.LENGTH_SHORT).show();
                    return;
                }

                Customer customerToSubmit;
                if (isEdit) {
                    customerToSubmit = customer;
                    customerToSubmit.setName(name);
                    customerToSubmit.setMobileNumber(mobile);
                    customerToSubmit.setProductLabel(product);
                    customerToSubmit.setCategory(category);
                    customerToSubmit.setNote(note);
                    executeUpdateRequest(customerToSubmit, dialog);
                } else {
                    customerToSubmit = new Customer(name, mobile, product, category, note);
                    executeAddRequest(customerToSubmit, dialog);
                }
            });
        });

        dialog.show();
    }

    private void executeAddRequest(Customer newCustomer, AlertDialog dialog) {
        apiService.addCustomer(newCustomer).enqueue(new Callback<ApiResponse>() {
            @Override
            public void onResponse(Call<ApiResponse> call, Response<ApiResponse> response) { handleCrudResponse(response, "Added", dialog); }
            @Override
            public void onFailure(Call<ApiResponse> call, Throwable t) { handleCrudFailure(t, dialog); }
        });
    }

    private void executeUpdateRequest(Customer updatedCustomer, AlertDialog dialog) {
        apiService.updateCustomer(updatedCustomer).enqueue(new Callback<ApiResponse>() {
            @Override
            public void onResponse(Call<ApiResponse> call, Response<ApiResponse> response) { handleCrudResponse(response, "Updated", dialog); }
            @Override
            public void onFailure(Call<ApiResponse> call, Throwable t) { handleCrudFailure(t, dialog); }
        });
    }

    private void handleCrudResponse(Response<ApiResponse> response, String action, AlertDialog dialog) {
        String message;
        if (response.isSuccessful() && response.body().isSuccess()) {
            message = response.body().getMessage();
            loadCustomers(null);
            dialog.dismiss();
        } else {
            message = "Failed to " + action.toLowerCase() + " customer.";
            try {
                message = response.errorBody() != null ? new org.json.JSONObject(response.errorBody().string()).getString("message") : message;
            } catch (Exception e) {
                Log.e(TAG, "Error parsing API error body: " + e.getMessage());
            }
        }
        Toast.makeText(MainActivity.this, message, Toast.LENGTH_LONG).show();
    }

    private void handleCrudFailure(Throwable t, AlertDialog dialog) {
        Log.e(TAG, "Network failure for CRUD operation", t);
        Toast.makeText(MainActivity.this, "Network error: Could not connect to API.", Toast.LENGTH_LONG).show();
    }

    private void startCsvImportProcess() {
        filePickerLauncher.launch("text/csv");
        Toast.makeText(this, "Select a CSV file for import.", Toast.LENGTH_LONG).show();
    }

    private void handleCsvFileImport(Uri uri) {
        int totalCount = 0;
        int successCount = 0;
        try (InputStream inputStream = getContentResolver().openInputStream(uri);
             BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
            String line;
            boolean isFirstLine = true;
            while ((line = reader.readLine()) != null) {
                if (isFirstLine) {
                    isFirstLine = false;
                    continue;
                }
                String[] tokens = line.split(",", -1);

                if (tokens.length >= 4) {
                    totalCount++;
                    String name = tokens[0].trim();
                    String mobile = tokens[1].trim();
                    String product = tokens[2].trim();
                    String category = tokens[3].trim();
                    if (!name.isEmpty() && mobile.length() >= 10) {
                        // TODO: Re-implement API call to bulk_add.php here
                        successCount++;
                    }
                }
            }
            Toast.makeText(this, "CSV reading complete. Found " + totalCount + " records. Successfully processed " + successCount + " valid records.", Toast.LENGTH_LONG).show();
        } catch (Exception e) {
            Log.e(TAG, "Error processing CSV file", e);
            Toast.makeText(this, "Error reading file: " + e.getMessage(), Toast.LENGTH_LONG).show();
        }
    }

    public void loadCustomers(String query) {
        apiService.getCustomers(query).enqueue(new Callback<List<Customer>>() {
            @Override
            public void onResponse(Call<List<Customer>> call, Response<List<Customer>> response) {
                if (response.isSuccessful() && response.body() != null) {
                    List<Customer> customers = response.body();
                    if (customers.isEmpty()) {
                        recyclerView.setVisibility(View.GONE);
                        emptyView.setVisibility(View.VISIBLE);
                    } else {
                        recyclerView.setVisibility(View.VISIBLE);
                        emptyView.setVisibility(View.GONE);
                        customerAdapter.setCustomers(customers);
                    }
                } else {
                    Toast.makeText(MainActivity.this, "Failed to load data.", Toast.LENGTH_SHORT).show();
                    recyclerView.setVisibility(View.GONE);
                    emptyView.setVisibility(View.VISIBLE);
                }
            }
            @Override
            public void onFailure(Call<List<Customer>> call, Throwable t) {
                Log.e(TAG, "Network error loading customers", t);
                Toast.makeText(MainActivity.this, "Network error: Check connection/URL.", Toast.LENGTH_LONG).show();
                recyclerView.setVisibility(View.GONE);
                emptyView.setVisibility(View.VISIBLE);
            }
        });
    }

    @Override
    public void onCustomerDelete(int id, String name) { confirmAndDeleteCustomer(id, name); }
    public void confirmAndDeleteCustomer(final int customerId, String customerName) {
        new AlertDialog.Builder(this)
                .setTitle("Delete Customer")
                .setMessage("Are you sure you want to delete " + customerName + "? This cannot be undone.")
                .setPositiveButton("Delete", (dialog, which) -> executeDeleteCustomer(customerId))
                .setNegativeButton("Cancel", null)
                .show();
    }
    private void executeDeleteCustomer(int customerId) {
        apiService.deleteCustomer(customerId).enqueue(new Callback<ApiResponse>() {
            @Override
            public void onResponse(Call<ApiResponse> call, Response<ApiResponse> response) {
                String message = "Deletion failed.";
                if (response.isSuccessful() && response.body() != null && response.body().isSuccess()) {
                    message = response.body().getMessage();
                    loadCustomers(null);
                } else if (response.errorBody() != null) {
                    Log.e(TAG, "Delete Error: " + response.errorBody().toString());
                }
                Toast.makeText(MainActivity.this, message, Toast.LENGTH_SHORT).show();
            }
            @Override
            public void onFailure(Call<ApiResponse> call, Throwable t) {
                Toast.makeText(MainActivity.this, "Network error during delete.", Toast.LENGTH_LONG).show();
            }
        });
    }

    private void handleBulkSendMessage() {
        List<Integer> selectedIds = customerAdapter.getSelectedCustomerIdsAndClear();
        if (selectedIds.isEmpty()) {
            Toast.makeText(this, "No customers selected.", Toast.LENGTH_SHORT).show();
            return;
        }
        String currentDateTime = Utils.getCurrentDateTimeForDb();
        Toast.makeText(this, "Updating status for " + selectedIds.size() + " customers...", Toast.LENGTH_LONG).show();
        for (int id : selectedIds) {
            apiService.updateStatus(id, 1, currentDateTime).enqueue(new Callback<ApiResponse>() {
                @Override
                public void onResponse(Call<ApiResponse> call, Response<ApiResponse> response) {
                    if (!response.isSuccessful()) {
                        Log.e(TAG, "Failed status update for ID: " + id);
                    }
                }
                @Override public void onFailure(Call<ApiResponse> call, Throwable t) { /* handle network failure */ }
            });
        }
        recyclerView.postDelayed(() -> loadCustomers(null), 1000);
    }
}