<?php

namespace App\Http\Controllers;

use App\Coat;
use App\Curtain;
use App\CurtainReorder;
use App\Dress;
use App\MailSetting;
use App\TailorPayment;
use App\Support\NumberFormatter;
use App\User;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Mail;
use Illuminate\Validation\Rule;
use Spatie\Permission\Models\Role;
use App\Mail\TailorCreate;
use App\Pant;
use App\Tailor;
use App\TailoringCategory;
use App\TailoringProduct;
use App\Waiscoat;
use App\Services\MainCashAccount;
use Illuminate\Support\Facades\DB;
use Exception;

class TailorController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $role = Role::find(Auth::user()->role_id);
        if ($role->hasPermissionTo('tailors-index')) {
            $permissions = Role::findByName($role->name)->permissions;
            foreach ($permissions as $permission)
                $all_permission[] = $permission->name;
            if (empty($all_permission))
                $all_permission[] = 'dummy text';
            $role_id = $role->id;
            $numberOfTailor = Tailor::where('is_active', true)->count();
            return view('backend.tailoringproduct.tailor.index', compact('numberOfTailor', 'all_permission', 'role_id'));
        } else
            return redirect()->back()->with('not_permitted', 'Sorry! You are not allowed to access this module');
    }

    public function tailorData(Request $request)
    {
        $columns = array(
            1 => 'name',
            2 => 'email',
            3 => 'phone',
            5 => 'tailor_fee',
            // 7–9 are computed, so skip them
            9 => 'address',
        );



        $totalData = Tailor::where('is_active', true)->count();
        $totalFiltered = $totalData;

        if ($request->input('length') != -1)
            $limit = $request->input('length');
        else
            $limit = $totalData;
        $start = $request->input('start');
        $orderColumn = $columns[$request->input('order.0.column')] ?? 'name';
        $order = 'tailors.' . $orderColumn;
        $dir = in_array($request->input('order.0.dir'), ['asc', 'desc']) ? $request->input('order.0.dir') : 'asc';
        if (empty($request->input('search.value'))) {

            $tailors = Tailor::with('catagory', 'waiscoat', 'coat', 'pant', 'dress', 'curtain')
                ->latest()
                ->offset($start)
                ->where('is_active', true)
                ->limit($limit)
                ->orderBy($order, $dir)
                ->get();
        } else {
            $search = $request->input('search.value');
            $tailors = Tailor::select('tailors.*')->where('is_active', true)
                ->with('catagory', 'waiscoat', 'coat', 'pant', 'dress', 'curtain')
                ->where(function ($query) use ($search) {
                    $query->where('tailors.name', 'LIKE', "%{$search}%")
                        ->orWhere('tailors.email', 'LIKE', "%{$search}%")
                        ->orWhere('tailors.phone', 'LIKE', "%{$search}%");
                })
                ->where('tailors.is_active', true)
                ->latest()
                ->offset($start)
                ->limit($limit)
                ->orderBy($order, $dir)
                ->get();


            $totalFiltered = Tailor::select('tailors.*')->where([['is_active', true]])
                ->with('catagory')
                ->orWhere([
                    ['tailors.name', 'LIKE', "%{$search}%"],
                    ['tailors.is_active', true],
                ])
                ->orWhere([
                    ['tailors.email', 'LIKE', "%{$search}%"],
                    ['tailors.is_active', true],
                ])
                ->orWhere([
                    ['tailors.phone', 'LIKE', "%{$search}%"],
                    ['tailors.is_active', true],
                ])
                ->count();
        }
        $data = array();
        if (!empty($tailors)) {
            foreach ($tailors as $key => $tailor) {
                $total_orders = 0;
                $paid_orders = 0;
                $unpaid_orders = 0;
                foreach (['waiscoat', 'coat', 'pant', 'dress', 'curtain'] as $relation) {
                    $items = $tailor->$relation;

                    // If it's a single model, wrap in array
                    if ($items instanceof \Illuminate\Database\Eloquent\Model) {
                        $items = [$items];
                    }

                    foreach ($items as $item) {
                        $total_orders++;

                        if ($item->is_paid) {
                            $paid_orders++;
                        } else {
                            $unpaid_orders++;
                        }
                    }
                }

                $nestedData['id'] = $tailor->id;
                $nestedData['key'] = $key;
                $nestedData['tailor_name'] = $tailor->name;
                $nestedData['tailor_email'] = $tailor->email ? $tailor->email : 'N/A';
                $nestedData['tailor_phone'] = $tailor->phone;
                $nestedData['work_type'] = $tailor->catagory ? trans('file.' . $tailor->catagory->name) : '';
                $nestedData['tailor_fee'] = implode('<br>', [
                    trans('file.Fabric Meter Fee') . ': ' . NumberFormatter::natural($tailor->fabric_meter_fee, config('decimal')),
                    trans('file.Netting Meter Fee') . ': ' . NumberFormatter::natural($tailor->netting_meter_fee, config('decimal')),
                    trans('file.Mattress Fee') . ': ' . NumberFormatter::natural($tailor->mattress_fee, config('decimal')),
                    trans('file.Pillow Fee') . ': ' . NumberFormatter::natural($tailor->pillow_fee, config('decimal')),
                    trans('file.Bolster Fee') . ': ' . NumberFormatter::natural($tailor->bolster_fee, config('decimal')),
                ]);
                $nestedData['total_orders'] = $total_orders;
                $nestedData['paid_orders'] = $paid_orders;
                $nestedData['unpaid_orders'] = $unpaid_orders;
                $nestedData['address'] = $tailor->address;


                $nestedData['options'] = '<div class="btn-group">
                            <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">' . trans("file.action") . '
                              <span class="caret"></span>
                              <span class="sr-only">Toggle Dropdown</span>
                            </button>
                            <ul class="dropdown-menu edit-options dropdown-menu-right dropdown-default" user="menu">
                            ';

                if (in_array("tailors-edit", $request['all_permission'])) {
                    $nestedData['options'] .= '<li>
                            <a href="' . route('tailor.edit', $tailor->id) . '" class="btn btn-link"><i class="fa fa-edit"></i> ' . trans('file.edit') . '</a>
                        </li>';
                }
                if (in_array("tailors-delete", $request['all_permission'])) {
                    $nestedData['options'] .= \Form::open(["route" => ["tailor.destroy", $tailor->id], "method" => "DELETE"]) . '
                            <li>
                              <button type="submit" class="btn btn-link" onclick="return confirmDelete()"><i class="fa fa-trash"></i> ' . trans("file.delete") . '</button>
                            </li>' . \Form::close() . '
                        </ul>
                    </div>';
                }





                $nestedData['tailor'] = array(
                    '["' . $tailor->id . '"]'
                );
                //$nestedData['imagedata'] = DNS1D::getBarcodePNG($product->code, $product->barcode_symbology);
                $data[] = $nestedData;
            }
        }

        $json_data = array(
            "draw"            => intval($request->input('draw')),
            "recordsTotal"    => intval($totalData),
            "recordsFiltered" => intval($totalFiltered),
            "data"            => $data
        );

        echo json_encode($json_data);
    }

    public function deletebyselection(Request $request)
    {
        if (!$this->userCanTailorPermission('tailors-delete')) {
            return 'Sorry! You are not allowed to access this module';
        }

        $tailor_id = $request['tailorIdArray'];
        foreach ($tailor_id as $id) {
            $lims_tailor_data = Tailor::findOrFail($id);
            $lims_tailor_data->is_active = false;
            $lims_tailor_data->save();
        }
        $this->cacheForget('tailor_list');
        $this->cacheForget('tailor_list_with_variant');
        return 'Tailor deleted successfully!';
    }

    public function tailorOrders($id)
    {
        $role = Role::find(Auth::user()->role_id);
        if ($role->hasPermissionTo('tailors-index')) {
            $permissions = Role::findByName($role->name)->permissions;
            foreach ($permissions as $permission)
                $all_permission[] = $permission->name;
            if (empty($all_permission))
                $all_permission[] = 'dummy text';
            $role_id = $role->id;
            $tailor = Tailor::findOrFail($id);

            $numberOfOrder = 0;
            foreach (['waiscoat', 'coat', 'pant', 'dress', 'curtain'] as $relation) {
                $items = $tailor->$relation;

                // If it's a single model, wrap in array
                if ($items instanceof \Illuminate\Database\Eloquent\Model) {
                    $items = [$items];
                }

                foreach ($items as $item) {
                    $numberOfOrder++;
                }
            }
            return view('backend.tailoringproduct.tailor.order', compact('tailor','numberOfOrder', 'all_permission', 'role_id', 'id'));
        } else
            return redirect()->back()->with('not_permitted', 'Sorry! You are not allowed to access this module');
    }

    public function tailorOrderData(Request $request, $id)
    {
        $columns = array(
            7 => 'created_at',
            8 => 'completion_date',
        );


        $tailor = Tailor::with('waiscoat', 'coat', 'pant', 'dress', 'curtain')->findOrFail($id);
        $total_orders = 0;
        foreach (['waiscoat', 'coat', 'pant', 'dress', 'curtain'] as $relation) {
            $items = $tailor->$relation;

            // Normalize to array if it's a single model
            if ($items instanceof \Illuminate\Database\Eloquent\Model) {
                $items = [$items];
            }

            foreach ($items as $item) {
                $total_orders++;
            }
        }
        $totalData = $total_orders;
        $totalFiltered = $totalData;
        if ($request->input('length') != -1)
            $limit = $request->input('length');
        else
            $limit = $totalData;
        $start = $request->input('start');
        $sortField = $columns[$request->input('order.0.column')] ?? 'created_at';

        $dir = $request->input('order.0.dir') ?? 'asc';
        $orders = collect();
        $paginatedOrders =  collect();
        $tailor = Tailor::with(
            'waiscoat.tailoringProduct.customer',
            'coat.tailoringProduct.customer',
            'pant.tailoringProduct.customer',
            'dress.tailoringProduct.customer',
            'curtain.tailoringProduct.customer',

        )->findOrFail($id);
        if (empty($request->input('search.value'))) {
            foreach (['waiscoat', 'coat', 'pant', 'dress', 'curtain'] as $relation) {
                $items = $tailor->$relation;

                if ($items instanceof \Illuminate\Database\Eloquent\Model) {
                    $items = collect([$items]);
                }
                foreach ($items as $item) {
                    $item->table = $relation;

                    // Attach customer if available
                    $item->customer = optional($item->tailoringProduct)->customer;
                    $item->created_at = optional($item->tailoringProduct)->created_at;
                    $item->completion_date = optional($item->tailoringProduct)->completion_date;

                    $orders->push($item);
                }
            }
            $orders = $dir === 'desc' ? $orders->sortByDesc($sortField) : $orders->sortBy($sortField);
            $paginatedOrders = $orders->slice($start, $limit)->values();
        } else {
            $search = $request->input('search.value');
            foreach (['waiscoat', 'coat', 'pant', 'dress', 'curtain'] as $relation) {
                // Only include the matching relation
                if ($search === strtolower($relation)) {
                    $items = $tailor->$relation;

                    if ($items instanceof \Illuminate\Database\Eloquent\Model) {
                        $items = collect([$items]);
                    }

                    foreach ($items as $item) {
                        $item->table = $relation; // tag the source table
                        // Attach customer if available
                        $item->customer = optional($item->tailoringProduct)->customer;
                        $item->created_at = optional($item->tailoringProduct)->created_at;
                        $item->completion_date = optional($item->tailoringProduct)->completion_date;
                        $orders->push($item);
                    }
                }
            }

            // Sort and paginate
            $orders = $dir === 'desc'
                ? $orders->sortByDesc($sortField)
                : $orders->sortBy($sortField);

            $totalFiltered = $orders->count();
            $paginatedOrders = $orders->slice($start, $limit)->values();
        }
        $data = array();
        if (!empty($paginatedOrders)) {

            foreach ($paginatedOrders as $key => $order) {
                $nestedData['id'] = $order->id;
                $nestedData['key'] = $key;
                $nestedData['order_name'] = trans('file.' . ucfirst($order->table));
                $nestedData['customer_name'] = optional($order->customer)->name ? $order->customer->name : 'N/A';
                $nestedData['status'] = $order->is_paid ? '<div class="badge badge-success">' . trans('file.paid_order') . '</div>' : '<div class="badge badge-danger">' . trans('file.unpaid_order') . '</div>';
                $feeBreakdown = $this->tailorOrderFeeBreakdown($order);
                $nestedData['tailor_fee'] = $this->tailorFeeBreakdownHtml($feeBreakdown);
                $nestedData['qty'] = $order->qty;
                $nestedData['total'] = NumberFormatter::natural($feeBreakdown['total'], config('decimal'));
                $nestedData['issue_date'] = optional($order->created_at)->format('d-m-Y') ?? 'N/A';
                $nestedData['completion_date'] = optional($order->completion_date)->format('d-m-Y') ?? 'N/A';

                $nestedData['options'] = '<div class="btn-group">
                            <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">' . trans("file.action") . '
                              <span class="caret"></span>
                              <span class="sr-only">Toggle Dropdown</span>
                            </button>
                            <ul class="dropdown-menu edit-options dropdown-menu-right dropdown-default" user="menu">
                                <li>
                                    <a href="' . route("tailoringproducts.printTailor", ['type' => $order->table, 'id' => $order->id]) . '" class="btn btn-link print-btn-link"><i class="fa fa-print"></i> ' . trans('file.Print') . '</a>
                                </li>';

                if (!$order->is_paid) {
                    $nestedData['options'] .= '<li>
                                    <a href="' . route("tailor.order.edit", ['type' => $order->table, 'id' => $order->id]) . '" class="btn btn-link"><i class="fa fa-edit"></i> ' . trans('file.Paid') . '</a>
                                </li>';
                }

                $nestedData['options'] .= '</ul></div>';







                $nestedData['order'] = array(
                    '["' . $order->id . '"]'
                );
                //$nestedData['imagedata'] = DNS1D::getBarcodePNG($product->code, $product->barcode_symbology);
                $data[] = $nestedData;
            }
        }
        $json_data = array(
            "draw"            => intval($request->input('draw')),
            "recordsTotal"    => intval($totalData),
            "recordsFiltered" => intval($totalFiltered),
            "data"            => $data
        );

        echo json_encode($json_data);
    }
    public function tailorOrderspay($type, $id)
    {
        if (!$this->userCanTailorPermission('tailors-edit')) {
            return redirect()->back()->with('not_permitted', 'Sorry! You are not allowed to access this module');
        }

        
        if ($type == 'waiscoat') {
            $order = Waiscoat::findOrFail($id);
            
     
            
            $order->is_paid = true;
            
            $order->save();
        }

        if ($type == 'coat') {
            $order = Coat::findOrFail($id);
            $order->is_paid = true;
         
            
            $order->save();
        }
        if ($type == 'pant') {
            $order = Pant::findOrFail($id);
            $order->is_paid = true;
            
        
            $order->save();
        }
        if ($type == 'dress') {
            $order = Dress::findOrFail($id);
            $order->is_paid = true;

            
            $order->save();
        }
        if ($type == 'curtain') {
            $order = Curtain::findOrFail($id);
            $order->is_paid = true;
            $order->save();
        }
        return redirect()->back()->with('message', 'Order updated');
    }

    public function myOrders(Request $request)
    {
        $tailor = $this->currentTailorAccount();
        if (!$tailor) {
            abort(403);
        }

        $this->validate($request, [
            'status' => ['nullable', Rule::in(['all', 'received', 'in_progress', 'reordered', 'finished'])],
            'month' => ['nullable', 'date_format:Y-m'],
            'search' => ['nullable', 'string', 'max:100'],
        ]);

        $selectedStatus = $request->input('status', 'received');
        $month = $request->input('month', '');
        $search = trim((string) $request->input('search', ''));

        $baseQuery = TailoringProduct::query()
            ->where([['is_active', true], ['type', 'Curtain']])
            ->whereHas('curtain', function ($query) use ($tailor) {
                $query->where('tailor_id', $tailor->id);
            });

        if ($month !== '') {
            $monthStart = Carbon::createFromFormat('Y-m-d', $month . '-01')->startOfMonth();
            $monthEnd = (clone $monthStart)->endOfMonth();
            $baseQuery->where(function ($query) use ($monthStart, $monthEnd) {
                $query->whereBetween('completion_date', [$monthStart->toDateString(), $monthEnd->toDateString()])
                    ->orWhereHas('curtain', function ($curtainQuery) {
                        $curtainQuery->where('tailor_status', 'reordered');
                    });
            });
        }

        if ($search !== '') {
            $baseQuery->where(function ($query) use ($search) {
                $query->where('code', 'LIKE', '%' . $search . '%')
                    ->orWhereHas('customer', function ($customerQuery) use ($search) {
                        $customerQuery->where('name', 'LIKE', '%' . $search . '%');
                    });
            });
        }

        $statusCounts = [];
        foreach (['received', 'in_progress', 'reordered', 'finished'] as $status) {
            $statusCounts[$status] = (clone $baseQuery)
                ->whereHas('curtain', function ($query) use ($status) {
                    $query->where('tailor_status', $status);
                })
                ->count();
        }
        $statusCounts['all'] = (clone $baseQuery)->count();

        if (!$request->filled('status') && $statusCounts['reordered'] > 0) {
            $selectedStatus = 'reordered';
        }

        $ordersQuery = (clone $baseQuery)->with([
                'customer',
                'curtain.tailor',
                'curtain.windowDetails',
                'curtain.doorDetails',
                'curtain.beddingDetails',
                'curtain.reorders.reorderedBy',
            ]);

        if ($selectedStatus !== 'all') {
            $ordersQuery->whereHas('curtain', function ($query) use ($selectedStatus) {
                $query->where('tailor_status', $selectedStatus);
            });
        }

        $orders = $ordersQuery
            ->orderBy('completion_date')
            ->latest('id')
            ->paginate(15)
            ->appends($request->only(['status', 'month', 'search']));

        $statusOptions = $this->tailorStatusOptions();

        return view('backend.tailoringproduct.tailor.my_orders', compact(
            'tailor',
            'orders',
            'statusOptions',
            'statusCounts',
            'selectedStatus',
            'month',
            'search'
        ));
    }

    public function updateMyOrderStatus(Request $request, $id)
    {
        $tailor = $this->currentTailorAccount();
        if (!$tailor) {
            abort(403);
        }

        $this->validate($request, [
            'tailor_status' => ['required', Rule::in(array_keys($this->tailorStatusOptions()))],
        ]);

        $curtain = Curtain::where([['id', $id], ['tailor_id', $tailor->id]])->firstOrFail();
        $oldStatus = $curtain->tailor_status;

        if ($request->tailor_status === 'reordered'
            || $oldStatus === 'finished'
            || ($oldStatus === 'reordered' && $request->tailor_status !== 'finished')) {
            return redirect()->back()->with('not_permitted', trans('file.This status change is not allowed'));
        }

        $curtain->tailor_status = $request->tailor_status;
        if ($request->tailor_status === 'finished' && $oldStatus !== 'finished') {
            $curtain->tailor_finished_at = now();
        } elseif ($request->tailor_status !== 'finished') {
            $curtain->tailor_finished_at = null;
        }
        $curtain->save();

        $product = $curtain->tailoringProduct;
        if ($product) {
            $product->status = $request->tailor_status === 'finished' ? 'completed' : 'pending';
            $product->save();
        }

        if ($oldStatus === 'reordered' && $request->tailor_status === 'finished') {
            CurtainReorder::where('curtain_id', $curtain->id)
                ->whereNull('resolved_at')
                ->latest('reordered_at')
                ->limit(1)
                ->update(['resolved_at' => now()]);
        }

        return redirect()->back()->with('message', trans('file.Status updated successfully'));
    }

    public function monthlySummary(Request $request)
    {
        if (!$this->userCanTailorPermission('tailors-index')) {
            return redirect()->back()->with('not_permitted', 'Sorry! You are not allowed to access this module');
        }

        $this->validate($request, [
            'tailor_id' => ['nullable', 'exists:tailors,id'],
            'month' => ['nullable', 'date_format:Y-m'],
        ]);

        $tailors = Tailor::where('is_active', true)->orderBy('name')->get();
        $selectedTailorId = $request->input('tailor_id') ?: optional($tailors->first())->id;
        $month = $request->input('month') ?: now()->format('Y-m');
        $tailor = $selectedTailorId ? Tailor::find($selectedTailorId) : null;
        $summary = $tailor ? $this->tailorMonthlySummaryData($tailor, $month) : $this->emptyTailorMonthlySummary($month);
        $isTailorView = false;

        return view('backend.tailoringproduct.tailor.monthly_summary', compact('tailors', 'tailor', 'selectedTailorId', 'month', 'summary', 'isTailorView'));
    }

    public function myMonthlySummary(Request $request)
    {
        $tailor = $this->currentTailorAccount();
        if (!$tailor) {
            abort(403);
        }

        $this->validate($request, [
            'month' => ['nullable', 'date_format:Y-m'],
        ]);

        $month = $request->input('month') ?: now()->format('Y-m');
        $summary = $this->tailorMonthlySummaryData($tailor, $month);
        $tailors = collect([$tailor]);
        $selectedTailorId = $tailor->id;
        $isTailorView = true;

        return view('backend.tailoringproduct.tailor.monthly_summary', compact('tailors', 'tailor', 'selectedTailorId', 'month', 'summary', 'isTailorView'));
    }

    public function storeMonthlyPayment(Request $request)
    {
        if (!$this->userCanTailorPermission('tailors-edit')) {
            return redirect()->back()->with('not_permitted', 'Sorry! You are not allowed to access this module');
        }

        $this->validate($request, [
            'tailor_id' => ['required', 'exists:tailors,id'],
            'payment_month' => ['required', 'date_format:Y-m'],
            'payment_type' => ['required', Rule::in(['regular', 'advance'])],
            'amount' => ['required', 'numeric', 'min:0.01'],
            'paid_at' => ['nullable', 'date'],
            'note' => ['nullable', 'string'],
        ]);

        $tailor = Tailor::findOrFail($request->tailor_id);
        $summary = $this->tailorMonthlySummaryData($tailor, $request->payment_month);

        if ($request->payment_type === 'regular') {
            if ((float) $summary['due_total'] <= 0) {
                return redirect()->back()
                    ->withInput()
                    ->withErrors(['amount' => trans('file.No outstanding balance for this month')]);
            }

            if ((float) $request->amount > (float) $summary['due_total']) {
                return redirect()->back()
                    ->withInput()
                    ->withErrors(['amount' => trans('file.Payment cannot exceed outstanding balance', [
                        'amount' => NumberFormatter::natural($summary['due_total'], config('decimal')),
                    ])]);
            }
        }

        try {
            DB::transaction(function () use ($request, $tailor) {
                $payment = TailorPayment::create([
                    'tailor_id' => $request->tailor_id,
                    'payment_month' => $request->payment_month,
                    'amount' => $request->amount,
                    'payment_type' => $request->payment_type,
                    'paid_at' => $request->paid_at ?: now()->toDateString(),
                    'note' => $request->note,
                    'created_by' => Auth::id(),
                ]);
                $transaction = app(MainCashAccount::class)->withdraw(
                    (float) $payment->amount,
                    'tailor_payment',
                    TailorPayment::class,
                    $payment->id,
                    'TAILOR-' . $payment->id,
                    trans('file.Tailor payment for', [
                        'tailor' => $tailor->name,
                        'month' => $payment->payment_month,
                    ]),
                    $payment->paid_at
                );
                $payment->financial_transaction_id = $transaction->id;
                $payment->save();
            });
        } catch (Exception $e) {
            return redirect()->back()->withInput()->with('not_permitted', $e->getMessage());
        }

        return redirect()
            ->route('tailor.monthlySummary', ['tailor_id' => $request->tailor_id, 'month' => $request->payment_month])
            ->with('message', trans('file.Payment recorded successfully'));
    }

    public function printMonthlySummary(Request $request)
    {
        if (!$this->userCanTailorPermission('tailors-index')) {
            return redirect()->back()->with('not_permitted', 'Sorry! You are not allowed to access this module');
        }

        $this->validate($request, [
            'tailor_id' => ['required', 'exists:tailors,id'],
            'month' => ['nullable', 'date_format:Y-m'],
        ]);

        $tailor = Tailor::findOrFail($request->input('tailor_id'));
        $month = $request->input('month') ?: now()->format('Y-m');
        $summary = $this->tailorMonthlySummaryData($tailor, $month);

        return view('backend.tailoringproduct.tailor.print_monthly_summary', compact('tailor', 'month', 'summary'));
    }

    public function printMyMonthlySummary(Request $request)
    {
        $tailor = $this->currentTailorAccount();
        if (!$tailor) {
            abort(403);
        }

        $this->validate($request, [
            'month' => ['nullable', 'date_format:Y-m'],
        ]);

        $month = $request->input('month') ?: now()->format('Y-m');
        $summary = $this->tailorMonthlySummaryData($tailor, $month);

        return view('backend.tailoringproduct.tailor.print_monthly_summary', compact('tailor', 'month', 'summary'));
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        $role = Role::find(Auth::user()->role_id);
        if ($role->hasPermissionTo('tailors-add')) {
            $lims_category_list = TailoringCategory::where([['is_active', true], ['name', 'Curtain']])->get();
            return view('backend.tailoringproduct.tailor.create', compact('lims_category_list'));
        } else
            return redirect()->back()->with('not_permitted', 'Sorry! You are not allowed to access this module');
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        if (!$this->userCanTailorPermission('tailors-add')) {
            return redirect()->back()->with('not_permitted', 'Sorry! You are not allowed to access this module');
        }

        $this->validate($request, [
            'name' => [
                'required',
                'max:255',
                Rule::unique('users')->where(function ($query) {
                    return $query->where('is_deleted', false);
                }),
            ],
            'email' => [
                'required',
                'email',
                'max:255',
                Rule::unique('users')->where(function ($query) {
                    return $query->where('is_deleted', false);
                }),
            ],
            'password' => ['required'],
            'phone' => [
                'max:255',
                Rule::unique('tailors')->where(function ($query) {
                    return $query->where('is_active', 1);
                }),
            ],
            'fabric_meter_fee' => ['required', 'numeric', 'min:0'],
            'netting_meter_fee' => ['required', 'numeric', 'min:0'],
            'mattress_fee' => ['required', 'numeric', 'min:0'],
            'pillow_fee' => ['required', 'numeric', 'min:0'],
            'bolster_fee' => ['required', 'numeric', 'min:0'],
            'under_cover_fee_method' => ['required', Rule::in(['corresponding', 'separate'])],
            'mattress_under_cover_fee' => ['required_if:under_cover_fee_method,separate', 'nullable', 'numeric', 'min:0'],
            'pillow_under_cover_fee' => ['required_if:under_cover_fee_method,separate', 'nullable', 'numeric', 'min:0'],
            'bolster_under_cover_fee' => ['required_if:under_cover_fee_method,separate', 'nullable', 'numeric', 'min:0'],
        ]);
        $curtainCategory = TailoringCategory::where([['is_active', true], ['name', 'Curtain']])->first();
        if (!$curtainCategory || (int) $request->category_id !== (int) $curtainCategory->id) {
            return redirect()->back()->with('not_permitted', 'Only Curtain tailor category is available for this store.');
        }
        $tailor_data = $request->only([
            'name',
            'email',
            'phone',
            'address',
            'tailor_fee',
            'password',
            'fabric_meter_fee',
            'netting_meter_fee',
            'mattress_fee',
            'pillow_fee',
            'bolster_fee',
            'under_cover_fee_method',
            'mattress_under_cover_fee',
            'pillow_under_cover_fee',
            'bolster_under_cover_fee',
        ]);
        foreach (['mattress_under_cover_fee', 'pillow_under_cover_fee', 'bolster_under_cover_fee'] as $feeField) {
            $tailor_data[$feeField] = $tailor_data['under_cover_fee_method'] === 'separate'
                ? (float) ($tailor_data[$feeField] ?? 0)
                : 0;
        }
        //return $customer_data;
        $tailor_data['is_active'] = true;
        $message = 'Tailor';
        DB::transaction(function () use ($tailor_data, $request) {
            $user = User::create([
                'name' => $tailor_data['name'],
                'email' => $tailor_data['email'],
                'phone' => $tailor_data['phone'],
                'role_id' => $this->tailorUserRole()->id,
                'is_deleted' => false,
                'is_active' => true,
                'password' => bcrypt($tailor_data['password']),
            ]);
            $tailor_data['user_id'] = $user->id;
            unset($tailor_data['user'], $tailor_data['password']);
            $tailor_data['catagory_id'] = $request->category_id;
            Tailor::create($tailor_data);
        });
        $message .= ', User created successfully!';

        return redirect('tailor')->with('create_message', $message);
    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id) {}

    /**
     * Show the form for editing the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function edit($id)
    {
        $tailor = Tailor::findOrFail($id);
        $role = Role::find(Auth::user()->role_id);
        if ($role->hasPermissionTo('tailors-edit')) {
            $lims_category_list = TailoringCategory::where([['is_active', true], ['name', 'Curtain']])->get();
            return view('backend.tailoringproduct.tailor.edit', compact('tailor', 'lims_category_list'));
        } else
            return redirect()->back()->with('not_permitted', 'Sorry! You are not allowed to access this module');
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, $id)
    {
        if (!$this->userCanTailorPermission('tailors-edit')) {
            return redirect()->back()->with('not_permitted', 'Sorry! You are not allowed to access this module');
        }

        
        $curr = Tailor::findOrFail($id);
        $this->validate($request, [
            'name' => [
                'required',
                'max:255',
                Rule::unique('users')->ignore($curr->user_id)->where(function ($query) {
                    return $query->where('is_deleted', false);
                }),
            ],
            'email' => [
                'required',
                'email',
                'max:255',
                Rule::unique('users')->ignore($curr->user_id)->where(function ($query) {
                    return $query->where('is_deleted', false);
                }),
            ],
            'password' => [$curr->user_id ? 'nullable' : 'required'],
            'fabric_meter_fee' => ['required', 'numeric', 'min:0'],
            'netting_meter_fee' => ['required', 'numeric', 'min:0'],
            'mattress_fee' => ['required', 'numeric', 'min:0'],
            'pillow_fee' => ['required', 'numeric', 'min:0'],
            'bolster_fee' => ['required', 'numeric', 'min:0'],
            'under_cover_fee_method' => ['required', Rule::in(['corresponding', 'separate'])],
            'mattress_under_cover_fee' => ['required_if:under_cover_fee_method,separate', 'nullable', 'numeric', 'min:0'],
            'pillow_under_cover_fee' => ['required_if:under_cover_fee_method,separate', 'nullable', 'numeric', 'min:0'],
            'bolster_under_cover_fee' => ['required_if:under_cover_fee_method,separate', 'nullable', 'numeric', 'min:0'],
        ]);

        $tailor_data = $request->all();
        $curtainCategory = TailoringCategory::where([['is_active', true], ['name', 'Curtain']])->first();
        if (!$curtainCategory || (int)$tailor_data['catagory_id'] !== (int)$curtainCategory->id) {
            return redirect()->back()->with('not_permitted', 'Only Curtain tailor category is available for this store.');
        }
        //return $customer_data;
        $tailor_data['is_active'] = true;
        $message = 'Tailor';
        
        DB::transaction(function () use ($curr, $tailor_data) {
            $user_data = [
                'name' => $tailor_data['name'],
                'email' => $tailor_data['email'],
                'phone' => $tailor_data['phone'],
                'role_id' => $this->tailorUserRole()->id,
                'is_deleted' => false,
                'is_active' => true,
            ];
            if (!empty($tailor_data['password'])) {
                $user_data['password'] = bcrypt($tailor_data['password']);
            }
            $user = User::updateOrCreate(['id' => $curr->user_id], $user_data);

            $curr->update([
                'name' => $tailor_data['name'],
                'email' => $tailor_data['email'],
                'phone' => $tailor_data['phone'],
                'address' => $tailor_data['address'],
                'tailor_fee' => $tailor_data['tailor_fee'],
                'fabric_meter_fee' => $tailor_data['fabric_meter_fee'],
                'netting_meter_fee' => $tailor_data['netting_meter_fee'],
                'mattress_fee' => $tailor_data['mattress_fee'],
                'pillow_fee' => $tailor_data['pillow_fee'],
                'bolster_fee' => $tailor_data['bolster_fee'],
                'under_cover_fee_method' => $tailor_data['under_cover_fee_method'],
                'mattress_under_cover_fee' => $tailor_data['under_cover_fee_method'] === 'separate' ? ($tailor_data['mattress_under_cover_fee'] ?? 0) : 0,
                'pillow_under_cover_fee' => $tailor_data['under_cover_fee_method'] === 'separate' ? ($tailor_data['pillow_under_cover_fee'] ?? 0) : 0,
                'bolster_under_cover_fee' => $tailor_data['under_cover_fee_method'] === 'separate' ? ($tailor_data['bolster_under_cover_fee'] ?? 0) : 0,
                'catagory_id' => $tailor_data['catagory_id'],
                'user_id' => $user->id,
            ]);
        });
        $message .= ', User updated successfully!';

        return redirect('tailor')->with('create_message', $message);
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
        if (!$this->userCanTailorPermission('tailors-delete')) {
            return redirect()->back()->with('not_permitted', 'Sorry! You are not allowed to access this module');
        }

        if (!env('USER_VERIFIED')) {
            return redirect()->back()->with('not_permitted', 'This feature is disable for demo!');
        } else {
            $tailor = Tailor::findOrFail($id);
            $tailor->is_active = false;
            $tailor->waiscoat()->delete(); // deletes all related waiscoats
            $tailor->coat()->delete();
            $tailor->pant()->delete();
            $tailor->dress()->delete();
            $tailor->curtain()->delete();
            $tailor->save();
            return redirect()->back()->with('not_permitted', 'Data deleted successfully');
        }
    }

    private function currentTailorAccount()
    {
        return Auth::check()
            ? Tailor::where('user_id', Auth::id())->where('is_active', true)->first()
            : null;
    }

    private function tailorMonthlySummaryData(Tailor $tailor, string $month)
    {
        $start = Carbon::createFromFormat('Y-m-d', $month . '-01')->startOfMonth();
        $end = (clone $start)->endOfMonth();

        $activeCurtainOrder = function ($query) {
            $query->where('is_active', true)->where('type', 'Curtain');
        };

        $baseStatusQuery = Curtain::where('tailor_id', $tailor->id)
            ->whereHas('tailoringProduct', $activeCurtainOrder);

        $previousFinishedOrders = Curtain::with('beddingDetails')
            ->where('tailor_id', $tailor->id)
            ->whereNotNull('accepted_at')
            ->where('accepted_at', '<', $start)
            ->whereHas('tailoringProduct', $activeCurtainOrder)
            ->get();

        $previousEarnedTotal = $previousFinishedOrders->sum(function ($curtain) use ($tailor) {
            return (float) $tailor->curtainFeeTotal($curtain);
        });

        $previousPaidTotal = (float) TailorPayment::where('tailor_id', $tailor->id)
            ->where('payment_month', '<', $month)
            ->sum('amount');

        $openingBalance = (float) $previousEarnedTotal - $previousPaidTotal;

        $finishedOrders = Curtain::with(['tailoringProduct.customer', 'beddingDetails'])
            ->where('tailor_id', $tailor->id)
            ->whereNotNull('accepted_at')
            ->whereBetween('accepted_at', [$start, $end])
            ->whereHas('tailoringProduct', $activeCurtainOrder)
            ->orderBy('accepted_at')
            ->get();

        $orders = [];
        $earnedTotal = 0;
        $breakdownTotals = [];

        foreach ($finishedOrders as $curtain) {
            $feeBreakdown = $tailor->curtainFeeBreakdown($curtain);
            $earnedTotal += (float) $feeBreakdown['total'];

            foreach ($feeBreakdown['rows'] as $row) {
                $label = $row['label'];
                if (!isset($breakdownTotals[$label])) {
                    $breakdownTotals[$label] = 0;
                }
                $breakdownTotals[$label] += (float) $row['total'];
            }

            $orders[] = [
                'code' => optional($curtain->tailoringProduct)->code,
                'customer' => optional(optional($curtain->tailoringProduct)->customer)->name ?: 'N/A',
                'finished_at' => optional($curtain->accepted_at)->format('d-m-Y'),
                'fee_breakdown' => $feeBreakdown,
                'total' => (float) $feeBreakdown['total'],
            ];
        }

        $payments = TailorPayment::where('tailor_id', $tailor->id)
            ->where('payment_month', $month)
            ->orderByDesc('paid_at')
            ->orderByDesc('id')
            ->get();

        $paidTotal = (float) $payments->sum('amount');
        $closingBalance = $openingBalance + $earnedTotal - $paidTotal;
        $openingDue = $openingBalance > 0 ? $openingBalance : 0;
        $openingCredit = $openingBalance < 0 ? abs($openingBalance) : 0;
        $closingDue = $closingBalance > 0 ? $closingBalance : 0;
        $closingCredit = $closingBalance < 0 ? abs($closingBalance) : 0;

        return [
            'month_label' => $start->format('F Y'),
            'finished_count' => $finishedOrders->count(),
            'in_progress_count' => (clone $baseStatusQuery)->where('tailor_status', 'in_progress')->count(),
            'received_count' => (clone $baseStatusQuery)->where('tailor_status', 'received')->count(),
            'reordered_count' => (clone $baseStatusQuery)->where('tailor_status', 'reordered')->count(),
            'opening_due' => $openingDue,
            'opening_credit' => $openingCredit,
            'earned_total' => $earnedTotal,
            'paid_total' => $paidTotal,
            'due_total' => $closingDue,
            'advance_total' => $closingCredit,
            'breakdown_totals' => $breakdownTotals,
            'orders' => $orders,
            'payments' => $payments,
        ];
    }

    private function emptyTailorMonthlySummary(string $month)
    {
        $start = Carbon::createFromFormat('Y-m-d', $month . '-01')->startOfMonth();

        return [
            'month_label' => $start->format('F Y'),
            'finished_count' => 0,
            'in_progress_count' => 0,
            'received_count' => 0,
            'reordered_count' => 0,
            'opening_due' => 0,
            'opening_credit' => 0,
            'earned_total' => 0,
            'paid_total' => 0,
            'due_total' => 0,
            'advance_total' => 0,
            'breakdown_totals' => [],
            'orders' => [],
            'payments' => collect(),
        ];
    }

    private function tailorStatusOptions()
    {
        return [
            'received' => trans('file.Received'),
            'in_progress' => trans('file.In Progress'),
            'reordered' => trans('file.Re-ordered'),
            'finished' => trans('file.Finished'),
        ];
    }

    private function tailorOrderFeeBreakdown($order)
    {
        if ($order instanceof Curtain && $order->tailor) {
            $order->loadMissing('beddingDetails');
            return $order->tailor->curtainFeeBreakdown($order);
        }

        $fee = (float) optional($order->tailor)->tailor_fee;
        $qty = (float) ($order->qty ?? 1);

        return [
            'rows' => [[
                'label' => trans('file.Tailor fee'),
                'qty' => $qty,
                'unit_fee' => $fee,
                'total' => $fee * $qty,
            ]],
            'total' => $fee * $qty,
        ];
    }

    private function tailorFeeBreakdownHtml(array $breakdown)
    {
        $lines = [];
        foreach ($breakdown['rows'] as $row) {
            if ((float) $row['qty'] <= 0 && (float) $row['unit_fee'] <= 0) {
                continue;
            }
            $lines[] = e($row['label']) . ': ' .
                NumberFormatter::natural($row['qty'], 2) . ' x ' .
                NumberFormatter::natural($row['unit_fee'], config('decimal')) . ' = ' .
                NumberFormatter::natural($row['total'], config('decimal'));
        }

        if (!$lines) {
            $lines[] = NumberFormatter::natural($breakdown['total'] ?? 0, config('decimal'));
        }

        return implode('<br>', $lines);
    }

    private function tailorUserRole()
    {
        $role = Role::where('name', 'Tailor')->first();
        if (!$role) {
            $role = Role::create([
                'name' => 'Tailor',
                'description' => 'Tailor account with limited order access',
                'guard_name' => 'web',
                'is_active' => true,
            ]);
        } else {
            $role->guard_name = $role->guard_name ?: 'web';
            $role->is_active = true;
            $role->save();
        }

        return $role;
    }

    private function userCanTailorPermission($permission)
    {
        $role = Role::find(Auth::user()->role_id);
        return $role && $role->hasPermissionTo($permission);
    }
}
