<?php

namespace App\Controllers\Admin;

use App\Controllers\BaseController;
use App\Models\BagSaleModel;
use App\Models\BagIssueModel;
use App\Models\BagReceivingModel;
use App\Models\BagInventoryModel;

class SalesReport extends BaseController
{
    /**
     * P5-01: 판매 대장 (일자별/기간별)
     */
    public function salesLedger()
    {
        helper('admin');
        $lgIdx = admin_effective_lg_idx();
        if (!$lgIdx) return redirect()->to(site_url('admin'))->with('error', '지자체를 선택해 주세요.');

        $startDate = $this->request->getGet('start_date') ?? date('Y-m-01');
        $endDate   = $this->request->getGet('end_date') ?? date('Y-m-d');
        $mode      = $this->request->getGet('mode') ?? 'daily'; // daily or period

        $saleModel = model(BagSaleModel::class);
        $db = \Config\Database::connect();

        if ($mode === 'daily') {
            $result = $db->query("
                SELECT bs_sale_date, bs_ds_name, bs_bag_code, bs_bag_name, bs_type,
                       SUM(ABS(bs_qty)) as total_qty,
                       SUM(bs_amount) as total_amount
                FROM bag_sale
                WHERE bs_lg_idx = ? AND bs_sale_date BETWEEN ? AND ? AND bs_type IN('sale','return')
                GROUP BY bs_sale_date, bs_ds_name, bs_bag_code, bs_bag_name, bs_type
                ORDER BY bs_sale_date DESC, bs_ds_name, bs_bag_code
            ", [$lgIdx, $startDate, $endDate])->getResult();
        } else {
            $result = $db->query("
                SELECT bs_ds_name, bs_bag_code, bs_bag_name,
                       SUM(CASE WHEN bs_type='sale' THEN ABS(bs_qty) ELSE 0 END) as sale_qty,
                       SUM(CASE WHEN bs_type='sale' THEN bs_amount ELSE 0 END) as sale_amount,
                       SUM(CASE WHEN bs_type='return' THEN ABS(bs_qty) ELSE 0 END) as return_qty,
                       SUM(CASE WHEN bs_type='return' THEN bs_amount ELSE 0 END) as return_amount
                FROM bag_sale
                WHERE bs_lg_idx = ? AND bs_sale_date BETWEEN ? AND ?
                GROUP BY bs_ds_name, bs_bag_code, bs_bag_name
                ORDER BY bs_ds_name, bs_bag_code
            ", [$lgIdx, $startDate, $endDate])->getResult();
        }

        return view('admin/layout', [
            'title'   => '판매 대장',
            'content' => view('admin/sales_report/sales_ledger', compact('result', 'startDate', 'endDate', 'mode')),
        ]);
    }

    /**
     * P5-02: 일계표
     */
    public function dailySummary()
    {
        helper('admin');
        $lgIdx = admin_effective_lg_idx();
        if (!$lgIdx) return redirect()->to(site_url('admin'))->with('error', '지자체를 선택해 주세요.');

        $date = $this->request->getGet('date') ?? date('Y-m-d');
        $db = \Config\Database::connect();

        // 당일 판매
        $daily = $db->query("
            SELECT bs_bag_code, bs_bag_name,
                   SUM(CASE WHEN bs_type='sale' THEN ABS(bs_qty) ELSE 0 END) as sale_qty,
                   SUM(CASE WHEN bs_type='sale' THEN bs_amount ELSE 0 END) as sale_amount
            FROM bag_sale
            WHERE bs_lg_idx = ? AND bs_sale_date = ?
            GROUP BY bs_bag_code, bs_bag_name
            ORDER BY bs_bag_code
        ", [$lgIdx, $date])->getResult();

        // 당월 누계
        $monthStart = date('Y-m-01', strtotime($date));
        $monthly = $db->query("
            SELECT bs_bag_code, bs_bag_name,
                   SUM(CASE WHEN bs_type='sale' THEN ABS(bs_qty) ELSE 0 END) as sale_qty,
                   SUM(CASE WHEN bs_type='sale' THEN bs_amount ELSE 0 END) as sale_amount
            FROM bag_sale
            WHERE bs_lg_idx = ? AND bs_sale_date BETWEEN ? AND ?
            GROUP BY bs_bag_code, bs_bag_name
            ORDER BY bs_bag_code
        ", [$lgIdx, $monthStart, $date])->getResult();

        return view('admin/layout', [
            'title'   => '일계표',
            'content' => view('admin/sales_report/daily_summary', compact('daily', 'monthly', 'date')),
        ]);
    }

    /**
     * P5-03: 기간별 판매현황
     */
    public function periodSales()
    {
        helper('admin');
        $lgIdx = admin_effective_lg_idx();
        if (!$lgIdx) return redirect()->to(site_url('admin'))->with('error', '지자체를 선택해 주세요.');

        $startDate = $this->request->getGet('start_date') ?? date('Y-m-01');
        $endDate   = $this->request->getGet('end_date') ?? date('Y-m-d');
        $db = \Config\Database::connect();

        $result = $db->query("
            SELECT bs_bag_code, bs_bag_name,
                   SUM(CASE WHEN bs_type='sale' THEN ABS(bs_qty) ELSE 0 END) as sale_qty,
                   SUM(CASE WHEN bs_type='sale' THEN bs_amount ELSE 0 END) as sale_amount,
                   SUM(CASE WHEN bs_type='return' THEN ABS(bs_qty) ELSE 0 END) as return_qty,
                   SUM(CASE WHEN bs_type='return' THEN bs_amount ELSE 0 END) as return_amount
            FROM bag_sale
            WHERE bs_lg_idx = ? AND bs_sale_date BETWEEN ? AND ?
            GROUP BY bs_bag_code, bs_bag_name
            ORDER BY bs_bag_code
        ", [$lgIdx, $startDate, $endDate])->getResult();

        return view('admin/layout', [
            'title'   => '기간별 판매현황',
            'content' => view('admin/sales_report/period_sales', compact('result', 'startDate', 'endDate')),
        ]);
    }

    /**
     * P5-04: 년 판매 현황 (월별)
     */
    public function yearlySales()
    {
        helper('admin');
        $lgIdx = admin_effective_lg_idx();
        if (!$lgIdx) return redirect()->to(site_url('admin'))->with('error', '지자체를 선택해 주세요.');

        $year = $this->request->getGet('year') ?? date('Y');
        $db = \Config\Database::connect();

        $result = $db->query("
            SELECT bs_bag_code, bs_bag_name,
                   SUM(CASE WHEN MONTH(bs_sale_date)=1  THEN ABS(bs_qty) ELSE 0 END) as m01,
                   SUM(CASE WHEN MONTH(bs_sale_date)=2  THEN ABS(bs_qty) ELSE 0 END) as m02,
                   SUM(CASE WHEN MONTH(bs_sale_date)=3  THEN ABS(bs_qty) ELSE 0 END) as m03,
                   SUM(CASE WHEN MONTH(bs_sale_date)=4  THEN ABS(bs_qty) ELSE 0 END) as m04,
                   SUM(CASE WHEN MONTH(bs_sale_date)=5  THEN ABS(bs_qty) ELSE 0 END) as m05,
                   SUM(CASE WHEN MONTH(bs_sale_date)=6  THEN ABS(bs_qty) ELSE 0 END) as m06,
                   SUM(CASE WHEN MONTH(bs_sale_date)=7  THEN ABS(bs_qty) ELSE 0 END) as m07,
                   SUM(CASE WHEN MONTH(bs_sale_date)=8  THEN ABS(bs_qty) ELSE 0 END) as m08,
                   SUM(CASE WHEN MONTH(bs_sale_date)=9  THEN ABS(bs_qty) ELSE 0 END) as m09,
                   SUM(CASE WHEN MONTH(bs_sale_date)=10 THEN ABS(bs_qty) ELSE 0 END) as m10,
                   SUM(CASE WHEN MONTH(bs_sale_date)=11 THEN ABS(bs_qty) ELSE 0 END) as m11,
                   SUM(CASE WHEN MONTH(bs_sale_date)=12 THEN ABS(bs_qty) ELSE 0 END) as m12,
                   SUM(ABS(bs_qty)) as total
            FROM bag_sale
            WHERE bs_lg_idx = ? AND YEAR(bs_sale_date) = ? AND bs_type = 'sale'
            GROUP BY bs_bag_code, bs_bag_name
            ORDER BY bs_bag_code
        ", [$lgIdx, $year])->getResult();

        return view('admin/layout', [
            'title'   => '년 판매 현황',
            'content' => view('admin/sales_report/yearly_sales', compact('result', 'year')),
        ]);
    }

    /**
     * P5-05: 지정판매소별 판매현황
     */
    public function shopSales()
    {
        helper('admin');
        $lgIdx = admin_effective_lg_idx();
        if (!$lgIdx) return redirect()->to(site_url('admin'))->with('error', '지자체를 선택해 주세요.');

        $startDate = $this->request->getGet('start_date') ?? date('Y-m-01');
        $endDate   = $this->request->getGet('end_date') ?? date('Y-m-d');
        $db = \Config\Database::connect();

        $result = $db->query("
            SELECT bs_ds_name,
                   SUM(CASE WHEN bs_type='sale' THEN ABS(bs_qty) ELSE 0 END) as sale_qty,
                   SUM(CASE WHEN bs_type='sale' THEN bs_amount ELSE 0 END) as sale_amount,
                   SUM(CASE WHEN bs_type='return' THEN ABS(bs_qty) ELSE 0 END) as return_qty,
                   SUM(CASE WHEN bs_type='return' THEN ABS(bs_amount) ELSE 0 END) as return_amount
            FROM bag_sale
            WHERE bs_lg_idx = ? AND bs_sale_date BETWEEN ? AND ?
            GROUP BY bs_ds_name
            ORDER BY bs_ds_name
        ", [$lgIdx, $startDate, $endDate])->getResult();

        return view('admin/layout', [
            'title'   => '지정판매소별 판매현황',
            'content' => view('admin/sales_report/shop_sales', compact('result', 'startDate', 'endDate')),
        ]);
    }

    /**
     * P5-06: 홈택스 세금계산서 엑셀 내보내기
     */
    public function hometaxExport()
    {
        helper(['admin', 'export']);
        $lgIdx = admin_effective_lg_idx();
        if (!$lgIdx) return redirect()->to(site_url('admin'))->with('error', '지자체를 선택해 주세요.');

        $startDate = $this->request->getGet('start_date') ?? date('Y-m-01');
        $endDate   = $this->request->getGet('end_date') ?? date('Y-m-d');

        $db = \Config\Database::connect();
        $rows = $db->query("
            SELECT bs.bs_sale_date, ds.ds_biz_no as buyer_biz_no, ds.ds_name as buyer_name,
                   bs.bs_bag_name, ABS(bs.bs_qty) as qty, bs.bs_unit_price, bs.bs_amount
            FROM bag_sale bs
            LEFT JOIN designated_shop ds ON bs.bs_ds_idx = ds.ds_idx
            WHERE bs.bs_lg_idx = ? AND bs.bs_sale_date BETWEEN ? AND ? AND bs.bs_type = 'sale'
            ORDER BY bs.bs_sale_date, ds.ds_name
        ", [$lgIdx, $startDate, $endDate])->getResult();

        // 지자체 정보 (공급자)
        $lg = model(\App\Models\LocalGovernmentModel::class)->find($lgIdx);
        $supplierBizNo = $lg->lg_biz_no ?? '';
        $supplierName  = $lg->lg_name ?? '';

        $csvRows = [];
        foreach ($rows as $row) {
            $amount = (int) $row->bs_amount;
            $tax    = (int) round($amount * 0.1);
            $csvRows[] = [
                str_replace('-', '', $row->bs_sale_date),  // 작성일자 (YYYYMMDD)
                $supplierBizNo,                             // 공급자사업자번호
                $supplierName,                              // 공급자상호
                $row->buyer_biz_no ?? '',                   // 공급받는자사업자번호
                $row->buyer_name ?? '',                     // 공급받는자상호
                $row->bs_bag_name,                          // 품목
                (int) $row->qty,                            // 수량
                (int) $row->bs_unit_price,                  // 단가
                $amount,                                    // 공급가액
                $tax,                                       // 세액
            ];
        }

        export_csv(
            '홈택스_세금계산서_' . date('Ymd') . '.csv',
            ['작성일자', '공급자사업자번호', '공급자상호', '공급받는자사업자번호', '공급받는자상호', '품목', '수량', '단가', '공급가액', '세액'],
            $csvRows
        );
    }

    /**
     * P5-08: 반품/파기 현황
     */
    public function returns()
    {
        helper('admin');
        $lgIdx = admin_effective_lg_idx();
        if (!$lgIdx) return redirect()->to(site_url('admin'))->with('error', '지자체를 선택해 주세요.');

        $startDate = $this->request->getGet('start_date') ?? date('Y-m-01');
        $endDate   = $this->request->getGet('end_date') ?? date('Y-m-d');
        $db = \Config\Database::connect();

        $result = $db->query("
            SELECT bs_sale_date, bs_ds_name, bs_bag_code, bs_bag_name, bs_type,
                   ABS(bs_qty) as qty, ABS(bs_amount) as amount
            FROM bag_sale
            WHERE bs_lg_idx = ? AND bs_sale_date BETWEEN ? AND ? AND bs_type IN('return','cancel')
            ORDER BY bs_sale_date DESC, bs_ds_name
        ", [$lgIdx, $startDate, $endDate])->getResult();

        return view('admin/layout', [
            'title'   => '반품/파기 현황',
            'content' => view('admin/sales_report/returns', compact('result', 'startDate', 'endDate')),
        ]);
    }

    /**
     * P5-10: LOT 수불 조회
     */
    public function lotFlow()
    {
        helper('admin');
        $lgIdx = admin_effective_lg_idx();
        if (!$lgIdx) return redirect()->to(site_url('admin'))->with('error', '지자체를 선택해 주세요.');

        $lotNo = $this->request->getGet('lot_no') ?? '';
        $order = null;
        $items = [];
        $receivings = [];

        if ($lotNo !== '') {
            $db = \Config\Database::connect();
            $order = $db->query("SELECT * FROM bag_order WHERE bo_lg_idx = ? AND bo_lot_no = ?", [$lgIdx, $lotNo])->getRow();
            if ($order) {
                $items = $db->query("SELECT * FROM bag_order_item WHERE boi_bo_idx = ? ORDER BY boi_bag_code", [(int) $order->bo_idx])->getResult();
                $receivings = $db->query("SELECT * FROM bag_receiving WHERE br_bo_idx = ? ORDER BY br_receive_date", [(int) $order->bo_idx])->getResult();
            }
        }

        return view('admin/layout', [
            'title'   => 'LOT 수불 조회',
            'content' => view('admin/sales_report/lot_flow', compact('lotNo', 'order', 'items', 'receivings')),
        ]);
    }

    /**
     * P5-11: 기타 입출고 목록
     */
    public function miscFlow()
    {
        helper('admin');
        $lgIdx = admin_effective_lg_idx();
        if (!$lgIdx) return redirect()->to(site_url('admin'))->with('error', '지자체를 선택해 주세요.');

        $startDate = $this->request->getGet('start_date') ?? date('Y-m-01');
        $endDate   = $this->request->getGet('end_date') ?? date('Y-m-d');
        $db = \Config\Database::connect();

        // bag_misc_flow 테이블이 존재하는지 확인
        $tableExists = $db->query("SHOW TABLES LIKE 'bag_misc_flow'")->getNumRows() > 0;
        $result = [];
        if ($tableExists) {
            $result = $db->query("
                SELECT * FROM bag_misc_flow
                WHERE bmf_lg_idx = ? AND bmf_date BETWEEN ? AND ?
                ORDER BY bmf_date DESC, bmf_idx DESC
            ", [$lgIdx, $startDate, $endDate])->getResult();
        }

        // 봉투 코드 목록
        $kindO = model(\App\Models\CodeKindModel::class)->where('ck_code', 'O')->first();
        $bagCodes = $kindO ? model(\App\Models\CodeDetailModel::class)->getByKind((int) $kindO->ck_idx, true) : [];

        return view('admin/layout', [
            'title'   => '기타 입출고',
            'content' => view('admin/sales_report/misc_flow', compact('result', 'startDate', 'endDate', 'bagCodes', 'tableExists')),
        ]);
    }

    /**
     * P5-11: 기타 입출고 등록 처리
     */
    public function miscFlowStore()
    {
        helper('admin');
        $lgIdx = admin_effective_lg_idx();
        if (!$lgIdx) return redirect()->to(site_url('admin/reports/misc-flow'))->with('error', '지자체를 선택해 주세요.');

        $rules = [
            'bmf_type'     => 'required|in_list[in,out]',
            'bmf_bag_code' => 'required|max_length[50]',
            'bmf_qty'      => 'required|is_natural_no_zero',
            'bmf_date'     => 'required|valid_date[Y-m-d]',
            'bmf_reason'   => 'required|max_length[200]',
        ];
        if (! $this->validate($rules)) {
            return redirect()->back()->withInput()->with('errors', $this->validator->getErrors());
        }

        $bagCode = $this->request->getPost('bmf_bag_code');
        $qty     = (int) $this->request->getPost('bmf_qty');
        $type    = $this->request->getPost('bmf_type');

        // 봉투명 조회
        $kindO = model(\App\Models\CodeKindModel::class)->where('ck_code', 'O')->first();
        $detail = $kindO ? model(\App\Models\CodeDetailModel::class)->where('cd_ck_idx', $kindO->ck_idx)->where('cd_code', $bagCode)->first() : null;
        $bagName = $detail ? $detail->cd_name : '';

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

        $db->query("
            INSERT INTO bag_misc_flow (bmf_lg_idx, bmf_type, bmf_bag_code, bmf_bag_name, bmf_qty, bmf_date, bmf_reason, bmf_regdate)
            VALUES (?, ?, ?, ?, ?, ?, ?, ?)
        ", [$lgIdx, $type, $bagCode, $bagName, $qty, $this->request->getPost('bmf_date'), $this->request->getPost('bmf_reason'), date('Y-m-d H:i:s')]);

        // 재고 조정
        $delta = ($type === 'in') ? $qty : -$qty;
        model(BagInventoryModel::class)->adjustQty($lgIdx, $bagCode, $bagName, $delta);

        $db->transComplete();

        return redirect()->to(site_url('admin/reports/misc-flow'))->with('success', '기타 입출고가 등록되었습니다.');
    }

    /**
     * P5-07: 봉투 수불 현황
     */
    public function supplyDemand()
    {
        helper('admin');
        $lgIdx = admin_effective_lg_idx();
        if (!$lgIdx) return redirect()->to(site_url('admin'))->with('error', '지자체를 선택해 주세요.');

        $startDate = $this->request->getGet('start_date') ?? date('Y-m-01');
        $endDate   = $this->request->getGet('end_date') ?? date('Y-m-d');
        $db = \Config\Database::connect();

        // 입고 합계
        $receiving = $db->query("
            SELECT br_bag_code, br_bag_name,
                   SUM(br_qty_sheet) as recv_qty
            FROM bag_receiving
            WHERE br_lg_idx = ? AND br_receive_date BETWEEN ? AND ?
            GROUP BY br_bag_code, br_bag_name
        ", [$lgIdx, $startDate, $endDate])->getResult();

        // 판매 합계
        $sales = $db->query("
            SELECT bs_bag_code, bs_bag_name,
                   SUM(CASE WHEN bs_type='sale' THEN ABS(bs_qty) ELSE 0 END) as sale_qty,
                   SUM(CASE WHEN bs_type='return' THEN ABS(bs_qty) ELSE 0 END) as return_qty
            FROM bag_sale
            WHERE bs_lg_idx = ? AND bs_sale_date BETWEEN ? AND ?
            GROUP BY bs_bag_code, bs_bag_name
        ", [$lgIdx, $startDate, $endDate])->getResult();

        // 불출 합계
        $issues = $db->query("
            SELECT bi2_bag_code, bi2_bag_name,
                   SUM(bi2_qty) as issue_qty
            FROM bag_issue
            WHERE bi2_lg_idx = ? AND bi2_issue_date BETWEEN ? AND ? AND bi2_status = 'normal'
            GROUP BY bi2_bag_code, bi2_bag_name
        ", [$lgIdx, $startDate, $endDate])->getResult();

        // 현재 재고
        $inventory = model(BagInventoryModel::class)->where('bi_lg_idx', $lgIdx)->findAll();

        return view('admin/layout', [
            'title'   => '봉투 수불 현황',
            'content' => view('admin/sales_report/supply_demand', compact('receiving', 'sales', 'issues', 'inventory', 'startDate', 'endDate')),
        ]);
    }
}
