<?php

namespace App\Controllers\Admin;

use App\Controllers\BaseController;
use App\Models\BagSaleModel;
use App\Models\BagInventoryModel;
use App\Models\DesignatedShopModel;
use App\Models\CodeKindModel;
use App\Models\CodeDetailModel;
use App\Models\BagPriceModel;

class BagSale extends BaseController
{
    private BagSaleModel $saleModel;

    public function __construct()
    {
        $this->saleModel = model(BagSaleModel::class);
    }

    public function index()
    {
        helper('admin');
        $lgIdx = admin_effective_lg_idx();
        if (! $lgIdx) {
            return redirect()->to(work_area_home_url())->with('error', '지자체를 선택해 주세요.');
        }

        $builder = $this->saleModel->where('bs_lg_idx', $lgIdx);
        $startDate = $this->request->getGet('start_date');
        $endDate   = $this->request->getGet('end_date');
        $type      = $this->request->getGet('type');
        if ($startDate) {
            $builder->where('bs_sale_date >=', $startDate);
        }
        if ($endDate) {
            $builder->where('bs_sale_date <=', $endDate);
        }
        if ($type) {
            $builder->where('bs_type', $type);
        }

        $list  = $builder->orderBy('bs_sale_date', 'DESC')->orderBy('bs_idx', 'DESC')->paginate(20);
        $pager = $this->saleModel->pager;

        return $this->renderWorkPage('판매/반품 관리', 'admin/bag_sale/index', compact('list', 'startDate', 'endDate', 'type', 'pager'));
    }

    public function export()
    {
        helper(['admin', 'export']);
        $lgIdx = admin_effective_lg_idx();
        if (! $lgIdx) {
            return redirect()->to(mgmt_url('bag-sales'))->with('error', '지자체를 선택해 주세요.');
        }

        $builder = $this->saleModel->where('bs_lg_idx', $lgIdx);
        $startDate = $this->request->getGet('start_date');
        $endDate   = $this->request->getGet('end_date');
        $type      = $this->request->getGet('type');
        if ($startDate) {
            $builder->where('bs_sale_date >=', $startDate);
        }
        if ($endDate) {
            $builder->where('bs_sale_date <=', $endDate);
        }
        if ($type) {
            $builder->where('bs_type', $type);
        }

        $list = $builder->orderBy('bs_sale_date', 'DESC')->orderBy('bs_idx', 'DESC')->findAll();

        $typeMap = ['sale' => '판매', 'return' => '반품', 'cancel' => '취소'];
        $rows    = [];
        foreach ($list as $row) {
            $rows[] = [
                $row->bs_idx,
                $row->bs_ds_name,
                $row->bs_sale_date,
                $row->bs_bag_code,
                $row->bs_bag_name,
                (int) $row->bs_qty,
                (int) $row->bs_unit_price,
                (int) $row->bs_amount,
                $typeMap[$row->bs_type] ?? $row->bs_type,
            ];
        }

        export_csv(
            '판매반품_' . date('Ymd') . '.csv',
            ['번호', '판매소', '판매일', '봉투코드', '봉투명', '수량', '단가', '금액', '구분'],
            $rows
        );
    }

    public function create()
    {
        helper('admin');
        $lgIdx = admin_effective_lg_idx();
        if (! $lgIdx) {
            return redirect()->to(mgmt_url('bag-sales'))->with('error', '지자체를 선택해 주세요.');
        }

        $shops = model(DesignatedShopModel::class)->where('ds_lg_idx', $lgIdx)->where('ds_state', 1)->findAll();
        $kind     = model(CodeKindModel::class)->where('ck_code', 'O')->first();
        $bagCodes = $kind ? model(CodeDetailModel::class)->getByKind((int) $kind->ck_idx, true, $lgIdx) : [];

        return $this->renderWorkPage('판매 등록', 'admin/bag_sale/create', compact('shops', 'bagCodes'));
    }

    public function store()
    {
        helper('admin');
        $lgIdx = admin_effective_lg_idx();

        $rules = [
            'bs_ds_idx'    => 'required|is_natural_no_zero',
            'bs_bag_code'  => 'required|max_length[50]',
            'bs_qty'       => 'required|is_natural_no_zero',
            'bs_sale_date' => 'required|valid_date[Y-m-d]',
            'bs_type'      => 'required|in_list[sale,return]',
        ];
        if (! $this->validate($rules)) {
            return redirect()->back()->withInput()->with('errors', $this->validator->getErrors());
        }

        $dsIdx   = (int) $this->request->getPost('bs_ds_idx');
        $bagCode = $this->request->getPost('bs_bag_code');
        $qty     = (int) $this->request->getPost('bs_qty');
        $type    = $this->request->getPost('bs_type');

        $shop   = model(DesignatedShopModel::class)->find($dsIdx);
        $kindO  = model(CodeKindModel::class)->where('ck_code', 'O')->first();
        $detail = $kindO ? model(CodeDetailModel::class)->findResolvedByKindAndCode((int) $kindO->ck_idx, (string) $bagCode, $lgIdx) : null;
        $price  = model(BagPriceModel::class)->latestActiveByBagCode($lgIdx, (string) $bagCode);
        $unitPrice = $price ? (float) $price->bp_consumer : 0;

        $actualQty = ($type === 'return') ? -$qty : $qty;

        $db = \Config\Database::connect();
        $db->transStart();

        $saleData = [
            'bs_lg_idx'     => $lgIdx,
            'bs_ds_idx'     => $dsIdx,
            'bs_ds_name'    => $shop ? $shop->ds_name : '',
            'bs_sale_date'  => $this->request->getPost('bs_sale_date'),
            'bs_bag_code'   => $bagCode,
            'bs_bag_name'   => $detail ? $detail->cd_name : '',
            'bs_qty'        => $actualQty,
            'bs_unit_price' => $unitPrice,
            'bs_amount'     => $unitPrice * abs($actualQty),
            'bs_type'       => $type,
            'bs_regdate'    => date('Y-m-d H:i:s'),
        ];
        $this->saleModel->insert($saleData);
        $bsIdx = (int) $this->saleModel->getInsertID();

        helper('audit');
        audit_log('create', 'bag_sale', $bsIdx, null, array_merge($saleData, ['bs_idx' => $bsIdx]));

        model(BagInventoryModel::class)->adjustQty($lgIdx, $bagCode, $detail ? $detail->cd_name : '', -$actualQty);

        $db->transComplete();

        $msg = ($type === 'sale') ? '판매 처리되었습니다.' : '반품 처리되었습니다.';

        return redirect()->to(mgmt_url('bag-sales'))->with('success', $msg);
    }
}
