<?php

namespace App\Controllers\Api;

use CodeIgniter\HTTP\ResponseInterface;

class FishingAreaController extends BaseApiController
{
    protected $format = 'json';
    protected $table = 'fishing_area';

    /**
     * 낚시지역 목록
     * GET /api/area/list
     */
    public function index()
    {
        $auth = $this->requireAuth();
        if ($auth instanceof ResponseInterface) {
            return $auth;
        }

        try {
            $page = (int) ($this->request->getGet('page') ?? 1);
            $perPage = (int) ($this->request->getGet('per_page') ?? 10);
            if ($page < 1) $page = 1;
            if ($perPage < 1) $perPage = 10;
            $offset = ($page - 1) * $perPage;

            $search = trim((string) $this->request->getGet('search'));

            $db = $this->getDB();
            $builder = $db->table($this->table);

            // soft delete 제외
            $builder->where('deleted_YN', 'N');

            if ($search !== '') {
                $builder->like('name', $search);
            }

            $total = $builder->countAllResults(false);

            $items = $builder
                ->select('id, name, created_at, updated_at')
                ->orderBy('id', 'DESC')
                ->limit($perPage, $offset)
                ->get()
                ->getResult();

            return $this->respondSuccess([
                'items'       => $items,
                'total'       => $total,
                'page'        => $page,
                'per_page'    => $perPage,
                'total_pages' => (int) ceil($total / $perPage),
            ]);
        } catch (\Exception $e) {
            log_message('error', 'FishingAreaController index error: ' . $e->getMessage());
            return $this->respondError('목록 조회 중 오류가 발생했습니다: ' . $e->getMessage(), ResponseInterface::HTTP_INTERNAL_SERVER_ERROR);
        }
    }

    /**
     * 낚시지역 등록
     * POST /api/area
     */
    public function create()
    {
        $auth = $this->requireAuth();
        if ($auth instanceof ResponseInterface) {
            return $auth;
        }

        try {
            $payload = $this->request->getJSON(true);
            if (!is_array($payload) || empty($payload)) {
                $payload = $this->request->getPost() ?? [];
            }

            $name = trim((string) ($payload['name'] ?? ''));

            // 지역명 검증: 1~20자, 필수
            if ($name === '') {
                return $this->respondError('지역명을 입력하세요.', ResponseInterface::HTTP_BAD_REQUEST);
            }
            if (mb_strlen($name) > 20) {
                return $this->respondError('지역명은 20자 이내로 입력하세요.', ResponseInterface::HTTP_BAD_REQUEST);
            }

            $db = $this->getDB();

            // 중복 검사 (soft delete 제외)
            $exists = $db->table($this->table)
                ->where('name', $name)
                ->where('deleted_YN', 'N')
                ->countAllResults();
            if ($exists > 0) {
                return $this->respondError('이미 등록된 지역명입니다.', ResponseInterface::HTTP_CONFLICT);
            }

            $insertData = [
                'name'       => $name,
                'created_at' => date('Y-m-d H:i:s'),
            ];

            if (!$db->table($this->table)->insert($insertData)) {
                return $this->respondError('등록에 실패했습니다.', ResponseInterface::HTTP_INTERNAL_SERVER_ERROR);
            }

            $newId = $db->insertID();
            $row = $db->table($this->table)->where('id', $newId)->get()->getRow();

            return $this->respondSuccess($row, '낚시지역이 등록되었습니다.', ResponseInterface::HTTP_CREATED);
        } catch (\Exception $e) {
            log_message('error', 'FishingAreaController create error: ' . $e->getMessage());
            return $this->respondError('등록 중 오류가 발생했습니다: ' . $e->getMessage(), ResponseInterface::HTTP_INTERNAL_SERVER_ERROR);
        }
    }

    /**
     * 낚시지역 상세 조회
     * GET /api/area/:id
     */
    public function show($id = null)
    {
        $auth = $this->requireAuth();
        if ($auth instanceof ResponseInterface) {
            return $auth;
        }

        if (empty($id)) {
            return $this->respondError('ID가 필요합니다.', ResponseInterface::HTTP_BAD_REQUEST);
        }

        try {
            $row = $this->getDB()->table($this->table)
                ->select('id, name, created_at, updated_at')
                ->where('id', (int) $id)
                ->where('deleted_YN', 'N')
                ->get()
                ->getRow();

            if (!$row) {
                return $this->respondError('해당 낚시지역을 찾을 수 없습니다.', ResponseInterface::HTTP_NOT_FOUND);
            }

            return $this->respondSuccess($row);
        } catch (\Exception $e) {
            log_message('error', 'FishingAreaController show error: ' . $e->getMessage());
            return $this->respondError('조회 중 오류가 발생했습니다: ' . $e->getMessage(), ResponseInterface::HTTP_INTERNAL_SERVER_ERROR);
        }
    }

    /**
     * 낚시지역 수정
     * PUT /api/area/:id
     */
    public function update($id = null)
    {
        $auth = $this->requireAuth();
        if ($auth instanceof ResponseInterface) {
            return $auth;
        }

        if (empty($id)) {
            return $this->respondError('ID가 필요합니다.', ResponseInterface::HTTP_BAD_REQUEST);
        }

        try {
            $payload = $this->request->getJSON(true);
            if (!is_array($payload) || empty($payload)) {
                $payload = $this->request->getRawInput() ?? [];
            }

            $name = trim((string) ($payload['name'] ?? ''));

            // 지역명 검증
            if ($name === '') {
                return $this->respondError('지역명을 입력하세요.', ResponseInterface::HTTP_BAD_REQUEST);
            }
            if (mb_strlen($name) > 20) {
                return $this->respondError('지역명은 20자 이내로 입력하세요.', ResponseInterface::HTTP_BAD_REQUEST);
            }

            $db = $this->getDB();

            // 대상 행 존재 확인
            $exists = $db->table($this->table)
                ->where('id', (int) $id)
                ->where('deleted_YN', 'N')
                ->countAllResults();
            if ($exists === 0) {
                return $this->respondError('해당 낚시지역을 찾을 수 없습니다.', ResponseInterface::HTTP_NOT_FOUND);
            }

            // 중복 검사 (자기 자신 제외)
            $dupe = $db->table($this->table)
                ->where('name', $name)
                ->where('id !=', (int) $id)
                ->where('deleted_YN', 'N')
                ->countAllResults();
            if ($dupe > 0) {
                return $this->respondError('이미 등록된 지역명입니다.', ResponseInterface::HTTP_CONFLICT);
            }

            $updateData = [
                'name'       => $name,
                'updated_at' => date('Y-m-d H:i:s'),
            ];

            $db->table($this->table)->where('id', (int) $id)->update($updateData);

            $row = $db->table($this->table)->where('id', (int) $id)->get()->getRow();
            return $this->respondSuccess($row, '낚시지역이 수정되었습니다.');
        } catch (\Exception $e) {
            log_message('error', 'FishingAreaController update error: ' . $e->getMessage());
            return $this->respondError('수정 중 오류가 발생했습니다: ' . $e->getMessage(), ResponseInterface::HTTP_INTERNAL_SERVER_ERROR);
        }
    }

    /**
     * 낚시지역 삭제 (soft delete)
     * DELETE /api/area/:id
     */
    public function delete($id = null)
    {
        $auth = $this->requireAuth();
        if ($auth instanceof ResponseInterface) {
            return $auth;
        }

        if (empty($id)) {
            return $this->respondError('ID가 필요합니다.', ResponseInterface::HTTP_BAD_REQUEST);
        }

        try {
            $db = $this->getDB();

            $exists = $db->table($this->table)
                ->where('id', (int) $id)
                ->where('deleted_YN', 'N')
                ->countAllResults();
            if ($exists === 0) {
                return $this->respondError('해당 낚시지역을 찾을 수 없습니다.', ResponseInterface::HTTP_NOT_FOUND);
            }

            // 해당 지역에 등록된 낚시어선/낚시터가 있으면 삭제 차단
            $onboardCount = $db->table('onboard')
                ->where('area_id', (int) $id)->where('deleted_YN', 'N')->countAllResults();
            $fishingCount = $db->table('fishing')
                ->where('area_id', (int) $id)->where('deleted_YN', 'N')->countAllResults();
            if (($onboardCount + $fishingCount) > 0) {
                return $this->respondError(
                    "해당 지역에 등록된 낚시어선/낚시터가 있어 삭제할 수 없습니다. (낚시어선 {$onboardCount} / 낚시터 {$fishingCount})",
                    ResponseInterface::HTTP_CONFLICT
                );
            }

            $db->table($this->table)
                ->where('id', (int) $id)
                ->update([
                    'deleted_YN' => 'Y',
                    'updated_at' => date('Y-m-d H:i:s'),
                ]);

            return $this->respondSuccess(null, '낚시지역이 삭제되었습니다.');
        } catch (\Exception $e) {
            log_message('error', 'FishingAreaController delete error: ' . $e->getMessage());
            return $this->respondError('삭제 중 오류가 발생했습니다: ' . $e->getMessage(), ResponseInterface::HTTP_INTERNAL_SERVER_ERROR);
        }
    }

    /**
     * 해당 지역에 속한 낚시어선 / 낚시터 통합 목록
     * GET /api/area/:id/places?limit=8
     */
    public function places($id = null)
    {
        $auth = $this->requireAuth();
        if ($auth instanceof ResponseInterface) {
            return $auth;
        }

        if (empty($id)) {
            return $this->respondError('지역 ID가 필요합니다.', ResponseInterface::HTTP_BAD_REQUEST);
        }

        try {
            $areaId = (int) $id;
            $limit = (int) ($this->request->getGet('limit') ?? 0);   // 지정되면 단순 LIMIT 모드
            $page  = (int) ($this->request->getGet('page') ?? 1);
            $perPage = (int) ($this->request->getGet('per_page') ?? 10);
            if ($page < 1) $page = 1;
            if ($perPage < 1) $perPage = 10;
            $offset = ($page - 1) * $perPage;

            $db = $this->getDB();

            // 지역명
            $area = $db->table($this->table)
                ->select('name')
                ->where('id', $areaId)->where('deleted_YN', 'N')
                ->get()->getRow();
            $areaName = $area ? $area->name : null;

            // 카운트
            $onboardCount = $db->table('onboard')
                ->where('area_id', $areaId)
                ->where('deleted_YN', 'N')
                ->countAllResults();
            $fishingCount = $db->table('fishing')
                ->where('area_id', $areaId)
                ->where('deleted_YN', 'N')
                ->countAllResults();
            $total = $onboardCount + $fishingCount;

            // UNION ALL — 통합 정렬
            if ($limit > 0) {
                // 단순 LIMIT 모드 (detail 페이지의 8개 미리보기)
                if ($limit > 1000) $limit = 1000;
                $tail = "LIMIT {$limit}";
                $totalPages = 1;
            } else {
                // 페이지네이션 모드 (전체보기 페이지)
                $tail = "LIMIT {$perPage} OFFSET {$offset}";
                $totalPages = (int) ceil($total / $perPage);
            }

            $sql = "(SELECT o.id, 'onboard' AS place_type, o.name, o.address, o.status_YN,
                            o.partnership_YN, ff.name AS field_name, o.created_at
                     FROM onboard o
                     LEFT JOIN fishing_field ff ON ff.id = o.field_id AND ff.deleted_YN = 'N'
                     WHERE o.area_id = ? AND o.deleted_YN = 'N')
                    UNION ALL
                    (SELECT fi.id, 'fishing' AS place_type, fi.name, fi.address, fi.status_YN,
                            fi.partnership_YN, ff2.name AS field_name, fi.created_at
                     FROM fishing fi
                     LEFT JOIN fishing_field ff2 ON ff2.id = fi.field_id AND ff2.deleted_YN = 'N'
                     WHERE fi.area_id = ? AND fi.deleted_YN = 'N')
                    ORDER BY created_at DESC
                    {$tail}";
            $items = $db->query($sql, [$areaId, $areaId])->getResult();

            return $this->respondSuccess([
                'items'         => $items,
                'onboard_count' => $onboardCount,
                'fishing_count' => $fishingCount,
                'area_name'     => $areaName,
                'total'         => $total,
                'page'          => $page,
                'per_page'      => $perPage,
                'total_pages'   => $totalPages,
            ]);
        } catch (\Exception $e) {
            log_message('error', 'FishingAreaController places error: ' . $e->getMessage());
            return $this->respondError('조회 중 오류: ' . $e->getMessage(), ResponseInterface::HTTP_INTERNAL_SERVER_ERROR);
        }
    }
}
