<?php

namespace App\Http\Controllers;

use App\Models\SocietyMaster;
use App\Models\User;
use App\Models\RoleMapping;
use App\Models\RoleMaster;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Carbon\Carbon;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\DB;

class SocietyMasterController extends Controller
{
    public function index()
    {
        $societies = SocietyMaster::with('societyType')->get()->map(function ($society) {
            // Explicitly include Email and Con_Password as null if not set
            $society->Email = $society->Email ?? null;
            $society->Con_Password = null; // Con_Password is not stored, always null
            return $society;
        });

        return response()->json([
            'status' => 'success',
            'message' => 'Societies retrieved successfully',
            'data' => $societies
        ], 200);
    }

    public function store(Request $request)
{
    $validator = Validator::make($request->all(), [
        'SocName' => 'required|string|max:25',
        'Soc_Sr_Name' => 'nullable|string|max:255',
        'Address' => 'nullable|string|max:35',
        'City' => 'nullable|string|max:50',
        'State' => 'nullable|string|max:50',
        'Country' => 'nullable|string|max:50',
        'PinNo' => 'nullable|digits:6',
        'SocURL' => 'nullable|string|max:1|in:Y,N',
        'Status' => 'nullable|string|max:1|in:A,I',
        'RegiDate' => 'nullable|date_format:d/m/Y',
        'RegiNumber' => 'nullable|string|max:25|unique:society_master,RegiNumber',
        'PhoneNo' => 'required|digits:10',
        'Email' => 'nullable|email|max:255',
        'Password' => 'nullable|string|min:8',
        'Con_Password' => 'nullable|string|same:Password',
        'Website' => 'nullable|url|max:255',
        'Enrl_Date' => 'nullable|date_format:d/m/Y',
        'St_Id' => 'nullable|exists:soci_type,St_Id',
    ], [
        'SocName.required' => 'Society name is required.',
        'PinNo.digits' => 'PIN code must be 6 digits.',
        'SocURL.in' => 'SocURL must be Y or N.',
        'Status.in' => 'Status must be A (Active) or I (Inactive).',
        'RegiDate.date_format' => 'Registration date must be in dd/mm/yyyy format.',
        'RegiNumber.unique' => 'This registration number already exists.',
        'PhoneNo.digits' => 'Phone number must be 10 digits.',
        'Email.email' => 'Email must be a valid email address.',
        'Password.required' => 'Password is required.',
        'Password.min' => 'Password must be at least 8 characters long.',
        'Con_Password.required' => 'Confirm password is required.',
        'Con_Password.same' => 'Confirm password must match the password.',
        'Enrl_Date.date_format' => 'Enrollment date must be in dd/mm/yyyy format.',
        'St_Id.exists' => 'The selected society type does not exist.',
    ]);

    if ($validator->fails()) {
        return response()->json([
            'status' => 'error',
            'message' => 'Validation failed',
            'errors' => $validator->errors()
        ], 422);
    }

    try {
        // Start a database transaction
        return DB::transaction(function () use ($request, $validator) {
            $data = $validator->validated();

            // Generate unique 6-character Short_Code (e.g., A134BC)
            $characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
            do {
                $shortCode = '';
                for ($i = 0; $i < 6; $i++) {
                    $shortCode .= $characters[rand(0, strlen($characters) - 1)];
                }
            } while (SocietyMaster::where('Short_Code', $shortCode)->exists());
            $data['Short_Code'] = $shortCode;

            // Set Soc_Sr_Name to Admin@<Short_Code> if not provided
            $data['Soc_Sr_Name'] = $data['Soc_Sr_Name'] ?? "Admin@{$shortCode}";

            // Parse dates to Y-m-d for storage
            if (isset($data['RegiDate'])) {
                $data['RegiDate'] = Carbon::createFromFormat('d/m/Y', $data['RegiDate'])->format('Y-m-d');
            }
            if (isset($data['Enrl_Date'])) {
                $data['Enrl_Date'] = Carbon::createFromFormat('d/m/Y', $data['Enrl_Date'])->format('Y-m-d');
            }

            // Hash the password for society
            $hashedPassword = Hash::make($data['Password']);
            $data['password'] = $hashedPassword;
            unset($data['Password']); // Remove Password from data as it's not stored directly
            unset($data['Con_Password']); // Remove Con_Password as it's not stored

            // Ensure Email is null if not provided
            $data['Email'] = $data['Email'] ?? null;

            // Create the society
            $society = SocietyMaster::create($data);
            $society->load('societyType');

            // Create corresponding user in users_master table
            $userData = [
                'U_Name' => $data['SocName'],
                'U_Mobile' => $data['PhoneNo'],
                'U_Password' => $hashedPassword,
                'U_Email' => $data['Email'],
                'U_Status' => $data['Status'] ?? 'A',
                'U_Gender' => null,
                'U_DOB' => null,
                'U_Image' => null,
                'SocId' => $society->SocId, // Add SocId from the created society
            ];

            $user = User::create($userData);

            // Check if Role_Id = 2 exists in role_master
            $role = RoleMaster::where('Role_Id', 2)->first();
            if (!$role) {
                throw new \Exception('Role with Role_Id 2 does not exist.');
            }

            // Create role mapping for the user with Role_Id = 2 and Default_Rid = 1
            $roleMappingData = [
                'U_Id' => $user->U_Id,
                'Role_Id' => 2,
                'Default_Rid' => 1,
            ];

            // Ensure no existing default role for the user
            $existingDefault = RoleMapping::where('U_Id', $user->U_Id)
                ->where('Default_Rid', 1)
                ->exists();
            if ($existingDefault) {
                throw new \Exception('User already has a default role.');
            }

            RoleMapping::create($roleMappingData);

            // Modify response to include Email and Con_Password as null
            $society->Email = $society->Email ?? null;
            $society->Con_Password = null; // Con_Password is not stored, always null

            return response()->json([
                'status' => 'success',
                'message' => 'Society, user, and role mapping created successfully',
                'data' => $society
            ], 201);
        });
    } catch (\Exception $e) {
        return response()->json([
            'status' => 'error',
            'message' => 'An unexpected error occurred: ' . $e->getMessage()
        ], 500);
    }
}

    public function show($id)
    {
        $society = SocietyMaster::with('societyType')->find($id);
        if (!$society) {
            return response()->json([
                'status' => 'error',
                'message' => 'Society not found'
            ], 404);
        }

        // Explicitly include Email and Con_Password as null if not set
        $society->Email = $society->Email ?? null;
        $society->Con_Password = null; // Con_Password is not stored, always null

        return response()->json([
            'status' => 'success',
            'message' => 'Society retrieved successfully',
            'data' => $society
        ], 200);
    }

    public function update(Request $request, $id)
    {
        $society = SocietyMaster::find($id);
        if (!$society) {
            return response()->json([
                'status' => 'error',
                'message' => 'Society not found'
            ], 404);
        }

        $validator = Validator::make($request->all(), [
            'SocName' => 'nullable|string|max:25',
            'Soc_Sr_Name' => 'nullable|string|max:255',
            'Address' => 'nullable|string|max:35',
            'City' => 'nullable|string|max:50',
            'State' => 'nullable|string|max:50',
            'Country' => 'nullable|string|max:50',
            'PinNo' => 'nullable|digits:6',
            'SocURL' => 'nullable|string|max:1|in:Y,N',
            'Status' => 'nullable|string|max:1|in:A,I',
            'RegiDate' => 'nullable|date_format:d/m/Y',
            'RegiNumber' => 'nullable|string|max:25|unique:society_master,RegiNumber,' . $id . ',SocId',
            'PhoneNo' => 'nullable|digits:10',
            'Email' => 'nullable|email|max:255',
            'Password' => 'nullable|string|min:8',
            'Con_Password' => 'nullable|string|same:Password',
            'Website' => 'nullable|url|max:255',
            'Enrl_Date' => 'nullable|date_format:d/m/Y',
            'St_Id' => 'nullable|exists:soci_type,St_Id',
        ], [
            'PinNo.digits' => 'PIN code must be 6 digits.',
            'SocURL.in' => 'SocURL must be Y or N.',
            'Status.in' => 'Status must be A (Active) or I (Inactive).',
            'RegiDate.date_format' => 'Registration date must be in dd/mm/yyyy format.',
            'RegiNumber.unique' => 'This registration number already exists.',
            'PhoneNo.digits' => 'Phone number must be 10 digits.',
            'Email.email' => 'Email must be a valid email address.',
            'Password.min' => 'Password must be at least 8 characters long.',
            'Con_Password.same' => 'Confirm password must match the password.',
            'Enrl_Date.date_format' => 'Enrollment date must be in dd/mm/yyyy format.',
            'St_Id.exists' => 'The selected society type does not exist.',
        ]);

        if ($validator->fails()) {
            return response()->json([
                'status' => 'error',
                'message' => 'Validation failed',
                'errors' => $validator->errors()
            ], 422);
        }

        try {
            $data = $request->only([
                'SocName', 'Soc_Sr_Name', 'Address', 'City', 'State', 'Country',
                'PinNo', 'SocURL', 'Status', 'RegiDate', 'RegiNumber', 'PhoneNo',
                'Email', 'Password', 'Website', 'Enrl_Date', 'St_Id'
            ]);

            // Parse dates to Y-m-d for storage
            if (isset($data['RegiDate'])) {
                $data['RegiDate'] = Carbon::createFromFormat('d/m/Y', $data['RegiDate'])->format('Y-m-d');
            }
            if (isset($data['Enrl_Date'])) {
                $data['Enrl_Date'] = $data['Enrl_Date']
                    ? Carbon::createFromFormat('d/m/Y', $data['Enrl_Date'])->format('Y-m-d')
                    : null;
            }

            // Hash the password if provided
            if (!empty($data['Password'])) {
                $data['password'] = Hash::make($data['Password']);
            }
            unset($data['Password']); // Remove Password from data as it's not stored directly
            unset($data['Con_Password']); // Remove Con_Password as it's not stored

            // Ensure Email is null if not provided
            $data['Email'] = $data['Email'] ?? null;

            $society->update($data);
            $society->load('societyType');

            // Modify response to include Email and Con_Password as null
            $society->Email = $society->Email ?? null;
            $society->Con_Password = null; // Con_Password is not stored, always null

            return response()->json([
                'status' => 'success',
                'message' => 'Society updated successfully',
                'data' => $society
            ], 200);
        } catch (\Exception $e) {
            return response()->json([
                'status' => 'error',
                'message' => 'An unexpected error occurred while updating the society.'
            ], 500);
        }
    }

    public function destroy($id)
    {
        $society = SocietyMaster::find($id);
        if (!$society) {
            return response()->json([
                'status' => 'error',
                'message' => 'Society not found'
            ], 404);
        }

        try {
            $society->delete();
            return response()->json([
                'status' => 'success',
                'message' => 'Society deleted successfully'
            ], 200);
        } catch (\Exception $e) {
            return response()->json([
                'status' => 'error',
                'message' => 'An unexpected error occurred while deleting the society.'
            ], 500);
        }
    }
}
