//
//  AddPetViewController.swift
//  VenusKitto
//
//  Created by Neoa on 2025/8/22.
//

import Foundation
import UIKit

// MARK: - AddPetViewController (添加宠物)
final class AddPetViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {

    private let scrollView = UIScrollView()
    private let contentView = UIView()

    private let avatarButton = UIButton(type: .custom)
    private let avatarHint = UILabel()

    private let nickCard = UIView()
    private let nickTitle = UILabel()
    private let nickField = UITextField()

    private let infoCard = UIView()

    // rows
    private let weightRow = InputRow(title: "体重", placeholder: "请输入体重(kg)", showsChevron: false, keyboard: .decimalPad)
    private let speciesRow = SelectRow(title: "种类")
    private let breedRow   = SelectRow(title: "品种")
    private let genderRow  = SelectRow(title: "性别")
    private let birthRow   = SelectRow(title: "出生日期")
    private let arriveRow  = SelectRow(title: "到家日期")

    private let cancelBtn = UIButton(type: .system)
    private let confirmBtn = UIButton(type: .system)

    private var selectedSpecies: String?
    private var selectedBreed: String? // For display (breed name)
    private var selectedBreedId: String? // For storing breedId
    private var selectedGender: String?
    private var birthDate: Date?
    private var arriveDate: Date?
    // For avatar upload
    private var avatarImageUrl: String?

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white
        title = "添加宠物"
        // Set custom back button image without text or back label
        if let backImage = UIImage(named: "AddPet385") {
            let backButton = UIBarButtonItem(image: backImage.withRenderingMode(.alwaysOriginal), style: .plain, target: self, action: #selector(tapCancel))
            navigationItem.leftBarButtonItem = backButton
        }
        layout()
        wire()
    }

    private func layout() {
        // scroll
        view.addSubview(scrollView)
        scrollView.translatesAutoresizingMaskIntoConstraints = false
        scrollView.showsVerticalScrollIndicator = false
        scrollView.keyboardDismissMode = .onDrag
        scrollView.addSubview(contentView)
        contentView.translatesAutoresizingMaskIntoConstraints = false

        NSLayoutConstraint.activate([
            scrollView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
            scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
            scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor),

            contentView.topAnchor.constraint(equalTo: scrollView.topAnchor),
            contentView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor),
            contentView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor),
            contentView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor),
            contentView.widthAnchor.constraint(equalTo: scrollView.widthAnchor)
        ])

        // avatar
        avatarButton.translatesAutoresizingMaskIntoConstraints = false
        avatarButton.setImage(UIImage(named: "Home372") ?? UIImage(systemName: "pawprint.circle")!, for: .normal)
        avatarButton.imageView?.contentMode = .scaleAspectFill
        avatarButton.layer.cornerRadius = 40
        avatarButton.clipsToBounds = true
        avatarButton.backgroundColor = UIColor(hex: "#FFF3D9")

        avatarHint.text = "点击上传头像"
        avatarHint.font = .systemFont(ofSize: 12)
        avatarHint.textColor = UIColor(hex: "#8B8B8B")
        avatarHint.textAlignment = .center
        avatarHint.translatesAutoresizingMaskIntoConstraints = false

        contentView.addSubview(avatarButton)
        contentView.addSubview(avatarHint)

        NSLayoutConstraint.activate([
            avatarButton.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 16),
            avatarButton.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 24),
            avatarButton.widthAnchor.constraint(equalToConstant: 80),
            avatarButton.heightAnchor.constraint(equalToConstant: 80),

            avatarHint.topAnchor.constraint(equalTo: avatarButton.bottomAnchor, constant: 6),
            avatarHint.centerXAnchor.constraint(equalTo: avatarButton.centerXAnchor)
        ])

        // Nick card
        nickCard.backgroundColor = .white
        nickCard.layer.cornerRadius = 12
        nickCard.layer.shadowColor = UIColor.black.cgColor
        nickCard.layer.shadowOpacity = 0.06
        nickCard.layer.shadowRadius = 6
        nickCard.layer.shadowOffset = .init(width: 0, height: 2)
        nickCard.translatesAutoresizingMaskIntoConstraints = false

        nickTitle.text = "昵称"
        nickTitle.font = .systemFont(ofSize: 14)
        nickTitle.textColor = UIColor(hex: "#5B5B5B")
        nickField.placeholder = "请输入昵称"
        nickField.font = .systemFont(ofSize: 14)
        nickField.textAlignment = .right
        nickField.clearButtonMode = .whileEditing

        let nickSeparator = DashedSeparator()

        [nickTitle, nickField].forEach { nickCard.addSubview($0); $0.translatesAutoresizingMaskIntoConstraints = false }
        contentView.addSubview(nickCard)

        NSLayoutConstraint.activate([
            nickCard.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 120),
            nickCard.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 24),
            nickCard.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -24),
            nickCard.heightAnchor.constraint(equalToConstant: 64),

            nickTitle.centerYAnchor.constraint(equalTo: nickCard.centerYAnchor),
            nickTitle.leadingAnchor.constraint(equalTo: nickCard.leadingAnchor, constant: 16),

            nickField.centerYAnchor.constraint(equalTo: nickCard.centerYAnchor),
            nickField.trailingAnchor.constraint(equalTo: nickCard.trailingAnchor, constant: -24),
            nickField.leadingAnchor.constraint(greaterThanOrEqualTo: nickTitle.trailingAnchor, constant: 12)
        ])

        // Info card
        infoCard.backgroundColor = .white
        infoCard.layer.cornerRadius = 12
        infoCard.layer.shadowColor = UIColor.black.cgColor
        infoCard.layer.shadowOpacity = 0.06
        infoCard.layer.shadowRadius = 6
        infoCard.layer.shadowOffset = .init(width: 0, height: 2)
        infoCard.translatesAutoresizingMaskIntoConstraints = false
        contentView.addSubview(infoCard)

        let rows: [UIView] = [weightRow, speciesRow, breedRow, genderRow, birthRow, arriveRow]
        rows.forEach { r in
            r.translatesAutoresizingMaskIntoConstraints = false
            infoCard.addSubview(r)
        }
        // separators
        let seps = (0..<(rows.count-1)).map { _ in DashedSeparator() }
        seps.forEach { s in infoCard.addSubview(s); s.translatesAutoresizingMaskIntoConstraints = false }

        NSLayoutConstraint.activate([
            infoCard.topAnchor.constraint(equalTo: nickCard.bottomAnchor, constant: 16),
            infoCard.leadingAnchor.constraint(equalTo: nickCard.leadingAnchor),
            infoCard.trailingAnchor.constraint(equalTo: nickCard.trailingAnchor)
        ])

        // Row heights
        let h: CGFloat = 52
        var prev: UIView? = nil
        for (idx, row) in rows.enumerated() {
            NSLayoutConstraint.activate([
                row.leadingAnchor.constraint(equalTo: infoCard.leadingAnchor, constant: 12),
                row.trailingAnchor.constraint(equalTo: infoCard.trailingAnchor, constant: -12),
                row.heightAnchor.constraint(equalToConstant: h)
            ])
            if let p = prev {
                row.topAnchor.constraint(equalTo: p.bottomAnchor).isActive = true
            } else {
                row.topAnchor.constraint(equalTo: infoCard.topAnchor).isActive = true
            }
            if idx < seps.count {
                let sep = seps[idx]
                NSLayoutConstraint.activate([
                    sep.leadingAnchor.constraint(equalTo: infoCard.leadingAnchor, constant: 12),
                    sep.trailingAnchor.constraint(equalTo: infoCard.trailingAnchor, constant: -12),
                    sep.topAnchor.constraint(equalTo: row.bottomAnchor),
                    sep.heightAnchor.constraint(equalToConstant: 1)
                ])
            }
            prev = row
        }
        prev!.bottomAnchor.constraint(equalTo: infoCard.bottomAnchor).isActive = true

        // Bottom buttons
        cancelBtn.setTitle("取消", for: .normal)
        cancelBtn.setTitleColor(.white, for: .normal)
        cancelBtn.backgroundColor = UIColor(hex: "#CFC7BD")
        cancelBtn.layer.cornerRadius = 22

        confirmBtn.setTitle("确定", for: .normal)
        confirmBtn.setTitleColor(.black, for: .normal)
        confirmBtn.backgroundColor = UIColor(hex: "#FFE059")
        confirmBtn.layer.cornerRadius = 22

        [cancelBtn, confirmBtn].forEach { v in
            contentView.addSubview(v)
            v.translatesAutoresizingMaskIntoConstraints = false
            v.heightAnchor.constraint(equalToConstant: 44).isActive = true
        }

        NSLayoutConstraint.activate([
            cancelBtn.topAnchor.constraint(equalTo: infoCard.bottomAnchor, constant: 28),
            cancelBtn.leadingAnchor.constraint(equalTo: infoCard.leadingAnchor),
            cancelBtn.trailingAnchor.constraint(equalTo: view.centerXAnchor, constant: -8),

            confirmBtn.topAnchor.constraint(equalTo: cancelBtn.topAnchor),
            confirmBtn.leadingAnchor.constraint(equalTo: view.centerXAnchor, constant: 8),
            confirmBtn.trailingAnchor.constraint(equalTo: infoCard.trailingAnchor),
            confirmBtn.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -28)
        ])
    }

    private func wire() {
        let tap = UITapGestureRecognizer(target: self, action: #selector(endEdit))
        tap.cancelsTouchesInView = false
        view.addGestureRecognizer(tap)

        avatarButton.addTarget(self, action: #selector(pickAvatar), for: .touchUpInside)
        cancelBtn.addTarget(self, action: #selector(tapCancel), for: .touchUpInside)
        confirmBtn.addTarget(self, action: #selector(tapConfirm), for: .touchUpInside)

        speciesRow.onTap = { [weak self] in self?.chooseSpecies() }
        breedRow.onTap   = { [weak self] in self?.chooseBreed() }
        genderRow.onTap  = { [weak self] in self?.chooseGender() }
        birthRow.onTap   = { [weak self] in self?.chooseDate(for: .birth) }
        arriveRow.onTap  = { [weak self] in self?.chooseDate(for: .arrive) }
    }

    @objc private func endEdit() { view.endEditing(true) }

    // MARK: - Actions
    // Upload avatar image
    @objc private func pickAvatar() {
        let picker = UIImagePickerController()
        picker.sourceType = .photoLibrary
        picker.delegate = self
        present(picker, animated: true)
    }

    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        if let img = info[.originalImage] as? UIImage {
            avatarButton.setImage(img, for: .normal)
            uploadAvatar(image: img) // Upload avatar after picking
        }
        picker.dismiss(animated: true)
    }

    private func uploadAvatar(image: UIImage) {
        guard let imageData = image.jpegData(compressionQuality: 0.7) else { return }
        let url = URL(string: "\(baseURL)/common/upload")!
        var request = URLRequest(url: url)
        request.httpMethod = "POST"
        request.setValue("application/json", forHTTPHeaderField: "Content-Type")
        if let token = UserDefaults.standard.string(forKey: "userToken") {
            request.setValue(token, forHTTPHeaderField: "Authorization")
        }

        // 创建多部分表单数据
        let boundary = "Boundary-\(UUID().uuidString)"
        request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
        
        var body = Data()
        
        // 添加图片数据
        body.append("--\(boundary)\r\n".data(using: .utf8)!)
        body.append("Content-Disposition: form-data; name=\"file\"; filename=\"avatar.jpg\"\r\n".data(using: .utf8)!)
        body.append("Content-Type: image/jpeg\r\n\r\n".data(using: .utf8)!)
        body.append(imageData)
        body.append("\r\n".data(using: .utf8)!)
        
        // 结束边界
        body.append("--\(boundary)--\r\n".data(using: .utf8)!)

        request.httpBody = body

        let task = URLSession.shared.dataTask(with: request) { [weak self] data, response, error in
            if let error = error {
                print("Error uploading image: \(error)")
                DispatchQueue.main.async {
                    self?.showToast(message: "头像上传失败，请重试。")
                }
                return
            }
            guard let data = data else {
                DispatchQueue.main.async {
                    self?.showToast(message: "头像上传失败，请重试。")
                }
                return
            }

            do {
                let decoder = JSONDecoder()
                let responseObject = try decoder.decode(UploadImageResponse.self, from: data)
                if responseObject.code == "200" {
                    // Get imageUrl and save it
                    self?.avatarImageUrl = responseObject.data.url
                    print("ssss \(String(describing: self?.avatarImageUrl))")
                    DispatchQueue.main.async {
                        self?.showToast(message: "头像上传成功！")
                    }
                } else {
                    print("Error: \(responseObject.msg ?? "Unknown error")")
                    DispatchQueue.main.async {
                        self?.showToast(message: "头像上传失败，请重试。")
                    }
                }
            } catch {
                print("Error decoding upload response: \(error)")
                DispatchQueue.main.async {
                    self?.showToast(message: "头像上传失败，请重试。")
                }
            }

        }
        task.resume()
    }

    @objc private func tapCancel() { navigationController?.popViewController(animated: true) }

    @objc private func tapConfirm() {
        // Fetch breedId from selectedBreedId and categoryId from selectedSpecies
        let breedId = Int(selectedBreedId ?? "") ?? 0
        let categoryId = getCategoryId(from: selectedSpecies)
        let userId = UserDefaults.standard.integer(forKey: "userId") // Fetch userId from UserDefaults (or other storage)

        // DateFormatter to format the dates in the desired format
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "yyyy-MM-dd"

        // Format the arrivalDate and birthDate
        let formattedArrivalDate = dateFormatter.string(from: arriveDate ?? Date())
        let formattedBirthDate = dateFormatter.string(from: birthDate ?? Date())

        // Collect other data for pet save
        let name = nickField.text ?? ""
        let weight = weightRow.text
        let petData = PetSaveRequest(
            arrivalDate: formattedArrivalDate,
            avatar: avatarImageUrl ?? "",
            birthDate: formattedBirthDate,
            breedId: breedId,
            categoryId: categoryId,
            createTime: "",
            gender: selectedGender ?? "",
            id: 0,
            name: name,
            nickname: nickField.text ?? "",
            updateTime: "",
            userId: userId,
            weight: Double(weight ?? "0") ?? 0
        )
        print("dkkd \(petData)")
        savePetData(petData)
    }

    // Helper methods to get categoryId

    private func getCategoryId(from species: String?) -> Int {
        // Replace with actual logic to fetch categoryId based on species
        switch species {
        case "狗": return 3
        case "猫": return 4
        default: return 0
        }
    }

    private func savePetData(_ petData: PetSaveRequest) {
        guard let url = URL(string: "\(baseURL)/petRecordPet/petSave") else { return }
        var request = URLRequest(url: url)
        request.httpMethod = "POST"
        request.setValue("application/json", forHTTPHeaderField: "Content-Type")
        if let token = UserDefaults.standard.string(forKey: "userToken") {
            request.setValue(token, forHTTPHeaderField: "Authorization")
        }

        do {
            let encoder = JSONEncoder()
            let body = try encoder.encode(petData)
            request.httpBody = body
        } catch {
            print("Error encoding pet data: \(error)")
            DispatchQueue.main.async {
                self.showToast(message: "宠物信息保存失败，请重试。")
            }
            return
        }

        let task = URLSession.shared.dataTask(with: request) { [weak self] data, response, error in
            if let error = error {
                print("Error saving pet: \(error)")
                DispatchQueue.main.async {
                    self?.showToast(message: "宠物信息保存失败，请重试。")
                }
                return
            }
            guard let data = data else {
                DispatchQueue.main.async {
                    self?.showToast(message: "宠物信息保存失败，请重试。")
                }
                return
            }

            do {
                if let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] {
                    if let code = json["code"] as? String, code != "500" {
                        print("Pet saved successfully!")
                        // 通知首页刷新宠物列表
                        let uidStr = UserDefaults.standard.string(forKey: "userId") ?? {
                            let v = UserDefaults.standard.integer(forKey: "userId"); return v == 0 ? "" : String(v)
                        }()
                        NotificationCenter.default.post(name: .petDidSave, object: nil, userInfo: ["userId": uidStr])
                        DispatchQueue.main.async {
                            self?.showToast(message: "宠物信息保存成功！")
                        }
                        // Add delay of 1.5 seconds before going back
                        DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) { [weak self] in
                            self?.navigationController?.popViewController(animated: true)
                        }
                    } else {
                        DispatchQueue.main.async {
                            self?.showToast(message: "宠物信息保存失败，请重试。")
                        }
                    }
                }
            } catch {
                print("Error decoding pet save response: \(error)")
                // 通知首页刷新宠物列表（异常也发通知）
                let uidStr = UserDefaults.standard.string(forKey: "userId") ?? {
                    let v = UserDefaults.standard.integer(forKey: "userId"); return v == 0 ? "" : String(v)
                }()
                NotificationCenter.default.post(name: .petDidSave, object: nil, userInfo: ["userId": uidStr])
                DispatchQueue.main.async {
                    self?.showToast(message: "宠物信息保存成功！")
                }
                DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) { [weak self] in
                    self?.navigationController?.popViewController(animated: true)
                }
            }
        }
        task.resume()
    }

    // MARK: - Present action sheet safely on iPad
    private func presentSheet(_ ac: UIAlertController, from source: UIView) {
        if let pop = ac.popoverPresentationController {
            // 优先用触发的控件作为锚点
            if source.window != nil {
                pop.sourceView = source
                pop.sourceRect = source.bounds
                pop.permittedArrowDirections = [.up, .down]
            } else {
                // 兜底：用整个视图中心作为锚点（极少数情况下 source 还未在窗口层级里）
                pop.sourceView = self.view
                pop.sourceRect = CGRect(x: self.view.bounds.midX, y: self.view.bounds.midY, width: 1, height: 1)
                pop.permittedArrowDirections = []
            }
        }
        self.present(ac, animated: true)
    }
    
    // MARK: - Toast
    private func showToast(message: String) {
        let toastLabel = UILabel(frame: CGRect(x: self.view.frame.size.width / 2 - 150, y: self.view.frame.size.height/2 - 50, width: 300, height: 50))
        toastLabel.backgroundColor = UIColor.black.withAlphaComponent(0.7)
        toastLabel.textColor = UIColor.white
        toastLabel.textAlignment = .center
        toastLabel.font = .systemFont(ofSize: 14)
        toastLabel.text = message
        toastLabel.alpha = 1.0
        toastLabel.layer.cornerRadius = 10
        toastLabel.clipsToBounds  =  true
        self.view.addSubview(toastLabel)

        UIView.animate(withDuration: 1, delay: 1, options: .curveEaseOut, animations: {
            toastLabel.alpha = 0.0
        }, completion: { _ in
            toastLabel.removeFromSuperview()
        })
    }

    // Models for requests and responses
    struct UploadImageResponse: Codable {
        let code: String
        let msg: String?
        let data: UploadImageData
    }

    struct UploadImageData: Codable {
        let url: String
    }

    struct PetSaveRequest: Codable {
        let arrivalDate: String
        let avatar: String
        let birthDate: String
        let breedId: Int
        let categoryId: Int
        let createTime: String
        let gender: String
        let id: Int
        let name: String
        let nickname: String
        let updateTime: String
        let userId: Int
        let weight: Double
    }

    struct PetSaveResponse: Codable {
        let code: String
        let msg: String?
        let data: PetSaveData?
    }

    struct PetSaveData: Codable {
        let petId: Int
    }

    private func chooseSpecies() {
        let ac = UIAlertController(title: "选择种类", message: nil, preferredStyle: .actionSheet)
        ["猫", "狗"].forEach { t in ac.addAction(UIAlertAction(title: t, style: .default, handler: { _ in
            self.selectedSpecies = t
            self.speciesRow.value = t
            // 清空品种
            self.selectedBreed = nil
            self.selectedBreedId = nil
            self.breedRow.value = "请选择"
        })) }
        ac.addAction(UIAlertAction(title: "取消", style: .cancel))
        // ✅ 关键：指定 popover 锚点
        presentSheet(ac, from: self.speciesRow)
    }

    private func chooseBreed() {
        guard let sp = selectedSpecies else {
            let ac = UIAlertController(title: "请先选择种类", message: nil, preferredStyle: .alert)
            ac.addAction(UIAlertAction(title: "确定", style: .default))
            present(ac, animated: true); return
        }
        let categoryId: Int
        switch sp {
        case "狗": categoryId = 3
        case "猫": categoryId = 4
        default: categoryId = 0
        }
        let vc = BreedPickerViewController(categoryId: categoryId, token: UserDefaults.standard.string(forKey: "userToken"))
        vc.onSelect = { [weak self] breedId, breedName in
            self?.selectedBreed = breedName
            self?.breedRow.value = breedName
            self?.selectedBreedId = breedId
            self?.navigationController?.popViewController(animated: true)
        }
        navigationController?.pushViewController(vc, animated: true)
    }

    private func chooseGender() {
        let ac = UIAlertController(title: "选择性别", message: nil, preferredStyle: .actionSheet)
        ["公", "母"].forEach { t in ac.addAction(UIAlertAction(title: t, style: .default, handler: { _ in
            self.selectedGender = t
            self.genderRow.value = t
        })) }
        ac.addAction(UIAlertAction(title: "取消", style: .cancel))
        // ✅ 关键：指定 popover 锚点
        presentSheet(ac, from: self.genderRow)
    }

    private enum DateKind { case birth, arrive }
    private func chooseDate(for kind: DateKind) {
        let initDate = (kind == .birth) ? (self.birthDate ?? Date()) : (self.arriveDate ?? Date())
        let vc = DatePickerSheetController(initial: initDate)
        vc.onDone = { [weak self] date in
            guard let self = self else { return }
            let fmt = DateFormatter(); fmt.dateFormat = "yyyy-MM-dd"
            let text = fmt.string(from: date)
            if kind == .birth { self.birthDate = date; self.birthRow.value = text }
            else { self.arriveDate = date; self.arriveRow.value = text }
        }
        present(vc, animated: false)
    }
}

// MARK: - Helper Views
final class DashedSeparator: UIView {
    private let shape = CAShapeLayer()
    override init(frame: CGRect) {
        super.init(frame: frame)
        backgroundColor = .clear
        shape.strokeColor = UIColor(hex: "#DADADA").cgColor
        shape.lineDashPattern = [4, 4]
        shape.lineWidth = 1
        layer.addSublayer(shape)
    }
    required init?(coder: NSCoder) { fatalError() }
    override func layoutSubviews() {
        super.layoutSubviews()
        shape.frame = bounds
        let path = UIBezierPath()
        path.move(to: CGPoint(x: 0, y: bounds.midY))
        path.addLine(to: CGPoint(x: bounds.width, y: bounds.midY))
        shape.path = path.cgPath
    }
}

final class InputRow: UIView {
    private let titleLabel = UILabel()
    private let textField = UITextField()
    init(title: String, placeholder: String, showsChevron: Bool, keyboard: UIKeyboardType) {
        super.init(frame: .zero)
        titleLabel.text = title
        titleLabel.font = .systemFont(ofSize: 14)
        titleLabel.textColor = UIColor(hex: "#5B5B5B")

        textField.placeholder = placeholder
        textField.font = .systemFont(ofSize: 14)
        textField.textAlignment = .right
        textField.keyboardType = keyboard

        addSubview(titleLabel)
        addSubview(textField)
        titleLabel.translatesAutoresizingMaskIntoConstraints = false
        textField.translatesAutoresizingMaskIntoConstraints = false

        NSLayoutConstraint.activate([
            titleLabel.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 4),
            titleLabel.centerYAnchor.constraint(equalTo: centerYAnchor),

            textField.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -16),
            textField.centerYAnchor.constraint(equalTo: centerYAnchor),
            textField.leadingAnchor.constraint(greaterThanOrEqualTo: titleLabel.trailingAnchor, constant: 8)
        ])
    }
    
    func setEnabled(_ enabled: Bool) {
        isUserInteractionEnabled = enabled
        textField.textColor = enabled ? UIColor(hex: "#8B8B8B") : UIColor(hex: "#C8C8C8")
        titleLabel.textColor = enabled ? UIColor(hex: "#5B5B5B") : UIColor(hex: "#A0A0A0")
    }

    required init?(coder: NSCoder) { fatalError() }
    var text: String {
        get { textField.text ?? "" }
        set { textField.text = newValue }
    }
}

final class SelectRow: UIControl {
    private let titleLabel = UILabel()
    private let valueLabel = UILabel()
    private let chevron = UIImageView(image: UIImage(systemName: "chevron.right"))

    var onTap: (() -> Void)?

    // 外部控制：显示/隐藏右侧箭头；启用/禁用交互与样式
    func setChevronHidden(_ hidden: Bool) {
        chevron.isHidden = hidden
    }
    func setEnabled(_ enabled: Bool) {
        isUserInteractionEnabled = enabled
        valueLabel.textColor = enabled ? UIColor(hex: "#8B8B8B") : UIColor(hex: "#C8C8C8")
        titleLabel.textColor = enabled ? UIColor(hex: "#5B5B5B") : UIColor(hex: "#A0A0A0")
    }
    
    init(title: String) {
        super.init(frame: .zero)
        addTarget(self, action: #selector(tap), for: .touchUpInside)
        titleLabel.text = title
        titleLabel.font = .systemFont(ofSize: 14)
        titleLabel.textColor = UIColor(hex: "#5B5B5B")

        valueLabel.text = "请选择"
        valueLabel.font = .systemFont(ofSize: 14)
        valueLabel.textColor = UIColor(hex: "#8B8B8B")
        valueLabel.textAlignment = .right

        chevron.tintColor = UIColor(hex: "#C1C1C1")
        chevron.setContentHuggingPriority(.required, for: .horizontal)

        [titleLabel, valueLabel, chevron].forEach { addSubview($0); $0.translatesAutoresizingMaskIntoConstraints = false }

        NSLayoutConstraint.activate([
            titleLabel.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 4),
            titleLabel.centerYAnchor.constraint(equalTo: centerYAnchor),

            chevron.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -2),
            chevron.centerYAnchor.constraint(equalTo: centerYAnchor),
            chevron.widthAnchor.constraint(equalToConstant: 10),

            valueLabel.trailingAnchor.constraint(equalTo: chevron.leadingAnchor, constant: -8),
            valueLabel.centerYAnchor.constraint(equalTo: centerYAnchor),
            valueLabel.leadingAnchor.constraint(greaterThanOrEqualTo: titleLabel.trailingAnchor, constant: 8)
        ])
    }
    required init?(coder: NSCoder) { fatalError() }

    @objc private func tap() { onTap?() }
    var value: String? { get { valueLabel.text } set { valueLabel.text = newValue } }
}


// MARK: - DatePickerSheetController (仿原型样式的日期弹窗)
final class DatePickerSheetController: UIViewController, UIPickerViewDataSource, UIPickerViewDelegate {
    var onDone: ((Date) -> Void)?

    private let initial: Date
    private let bg = UIControl()
    private let sheet = UIView()
    private let header = UIView()
    private let titleLabel = UILabel()
    private let closeBtn = UIButton(type: .custom)
    private let doneBtn = UIButton(type: .custom)
    private let picker = UIPickerView()
    private let highlight = UIView()

    private var years: [Int] = []
    private let months = Array(1...12)
    private var days: [Int] = []

    private var selYear: Int = 0
    private var selMonth: Int = 0
    private var selDay: Int = 0

    init(initial: Date) {
        self.initial = initial
        super.init(nibName: nil, bundle: nil)
        modalPresentationStyle = .overFullScreen
        modalTransitionStyle = .crossDissolve
    }
    required init?(coder: NSCoder) { fatalError() }

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .clear
        buildData()
        buildUI()
        applyInitialSelection()
    }

    private func buildData() {
        let cal = Calendar.current
        let nowYear = cal.component(.year, from: Date())
        years = Array((nowYear - 50)...(nowYear + 5))
    }

    private func buildUI() {
        // Dim background
        bg.backgroundColor = UIColor.black.withAlphaComponent(0.45)
        bg.addTarget(self, action: #selector(close), for: .touchUpInside)
        view.addSubview(bg)
        bg.translatesAutoresizingMaskIntoConstraints = false

        // Sheet
        sheet.backgroundColor = .white
        sheet.layer.cornerRadius = 16
        sheet.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
        view.addSubview(sheet)
        sheet.translatesAutoresizingMaskIntoConstraints = false

        // Header
        titleLabel.text = "选择时间"
        titleLabel.font = .systemFont(ofSize: 16, weight: .medium)
        titleLabel.textColor = UIColor(hex: "#2B2B2B")
        titleLabel.textAlignment = .center

        closeBtn.setImage(UIImage(named: "AddPet385"), for: .normal)
//        closeBtn.tintColor = UIColor(hex: "#2B2B2B")
        closeBtn.addTarget(self, action: #selector(close), for: .touchUpInside)

        doneBtn.setImage(UIImage(named: "AddPet389"), for: .normal)
//        doneBtn.tintColor = UIColor(hex: "#2B2B2B")
        doneBtn.addTarget(self, action: #selector(doneTap), for: .touchUpInside)

        header.translatesAutoresizingMaskIntoConstraints = false
        header.addSubview(titleLabel)
        header.addSubview(closeBtn)
        header.addSubview(doneBtn)
        [titleLabel, closeBtn, doneBtn].forEach { $0.translatesAutoresizingMaskIntoConstraints = false }

        // Picker
        picker.dataSource = self
        picker.delegate = self
        picker.translatesAutoresizingMaskIntoConstraints = false
        picker.backgroundColor = .clear

        // Highlight row (FFE059, 25% alpha)
        highlight.backgroundColor = UIColor(hex: "#FFE059").withAlphaComponent(0.25)
        highlight.layer.cornerRadius = 22
        highlight.isUserInteractionEnabled = false
        highlight.translatesAutoresizingMaskIntoConstraints = false

        sheet.addSubview(header)
        sheet.addSubview(picker)
        sheet.addSubview(highlight)

        // Layout
        NSLayoutConstraint.activate([
            bg.topAnchor.constraint(equalTo: view.topAnchor),
            bg.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            bg.trailingAnchor.constraint(equalTo: view.trailingAnchor),
            bg.bottomAnchor.constraint(equalTo: view.bottomAnchor),

            sheet.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            sheet.trailingAnchor.constraint(equalTo: view.trailingAnchor),
            sheet.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor),

            header.topAnchor.constraint(equalTo: sheet.topAnchor, constant: 8),
            header.leadingAnchor.constraint(equalTo: sheet.leadingAnchor, constant: 12),
            header.trailingAnchor.constraint(equalTo: sheet.trailingAnchor, constant: -12),
            header.heightAnchor.constraint(equalToConstant: 36),

            closeBtn.centerYAnchor.constraint(equalTo: header.centerYAnchor),
            closeBtn.leadingAnchor.constraint(equalTo: header.leadingAnchor),
            closeBtn.widthAnchor.constraint(equalToConstant: 28),
            closeBtn.heightAnchor.constraint(equalToConstant: 28),

            doneBtn.centerYAnchor.constraint(equalTo: header.centerYAnchor),
            doneBtn.trailingAnchor.constraint(equalTo: header.trailingAnchor),
            doneBtn.widthAnchor.constraint(equalToConstant: 28),
            doneBtn.heightAnchor.constraint(equalToConstant: 28),

            titleLabel.centerXAnchor.constraint(equalTo: header.centerXAnchor),
            titleLabel.centerYAnchor.constraint(equalTo: header.centerYAnchor),

            picker.topAnchor.constraint(equalTo: header.bottomAnchor, constant: 4),
            picker.leadingAnchor.constraint(equalTo: sheet.leadingAnchor),
            picker.trailingAnchor.constraint(equalTo: sheet.trailingAnchor),
            picker.bottomAnchor.constraint(equalTo: sheet.bottomAnchor),

            highlight.leadingAnchor.constraint(equalTo: sheet.leadingAnchor, constant: 16),
            highlight.trailingAnchor.constraint(equalTo: sheet.trailingAnchor, constant: -16),
            highlight.centerYAnchor.constraint(equalTo: picker.centerYAnchor),
            highlight.heightAnchor.constraint(equalToConstant: 44)
        ])
    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        // Present animation
        sheet.transform = CGAffineTransform(translationX: 0, y: 400)
        header.alpha = 0
        picker.alpha = 0
        bg.alpha = 0
        UIView.animate(withDuration: 0.25, delay: 0, options: [.curveEaseOut]) {
            self.sheet.transform = .identity
            self.header.alpha = 1
            self.picker.alpha = 1
            self.bg.alpha = 1
        }
    }

    // MARK: - Picker data
    func numberOfComponents(in pickerView: UIPickerView) -> Int { 3 }
    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        switch component {
        case 0: return years.count
        case 1: return months.count
        default: return days.count
        }
    }

    func pickerView(_ pickerView: UIPickerView, widthForComponent component: Int) -> CGFloat {
        let w = pickerView.bounds.width
        return component == 0 ? w * 0.4 : w * 0.3
    }

    func pickerView(_ pickerView: UIPickerView, rowHeightForComponent component: Int) -> CGFloat { 44 }

    func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
        let label = (view as? UILabel) ?? UILabel()
        label.font = .systemFont(ofSize: 18, weight: .medium)
        label.textAlignment = component == 0 ? .center : .center
        label.textColor = UIColor(hex: "#2B2B2B")
        switch component {
        case 0: label.text = "\(years[row])年"
        case 1: label.text = String(format: "%02d月", months[row])
        default: label.text = String(format: "%02d日", days[row])
        }
        // 变灰非选中项
        let isSelected = row == pickerView.selectedRow(inComponent: component)
        label.textColor = isSelected ? UIColor(hex: "#2B2B2B") : UIColor(hex: "#A8A8A8")
        return label
    }

    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
        switch component {
        case 0: selYear = years[row]
        case 1: selMonth = months[row]
        case 2: selDay = days[row]
        default: break
        }
        if component != 2 {
            rebuildDays()
            pickerView.reloadComponent(2)
        }
        // 让文字颜色即时更新
        pickerView.reloadComponent(component)
    }

    private func applyInitialSelection() {
        let cal = Calendar.current
        selYear = cal.component(.year, from: initial)
        selMonth = cal.component(.month, from: initial)
        selDay = cal.component(.day, from: initial)
        rebuildDays()

        if let yi = years.firstIndex(of: selYear) {
            picker.selectRow(yi, inComponent: 0, animated: false)
        }
        picker.selectRow(selMonth - 1, inComponent: 1, animated: false)
        if let di = days.firstIndex(of: selDay) {
            picker.selectRow(di, inComponent: 2, animated: false)
        }
        picker.reloadAllComponents()
    }

    private func rebuildDays() {
        let cal = Calendar.current
        var comps = DateComponents()
        comps.year = selYear
        comps.month = selMonth
        comps.day = 1
        let date = cal.date(from: comps) ?? Date()
        let range = cal.range(of: .day, in: .month, for: date) ?? 1..<31
        days = Array(range)
        if !days.contains(selDay) { selDay = days.last ?? 1 }
    }

    @objc private func close() { dismissAnimated() }

    @objc private func doneTap() {
        var comps = DateComponents()
        comps.year = selYear; comps.month = selMonth; comps.day = selDay
        let cal = Calendar.current
        let date = cal.date(from: comps) ?? Date()
        onDone?(date)
        dismissAnimated()
    }

    private func dismissAnimated() {
        UIView.animate(withDuration: 0.22, animations: {
            self.sheet.transform = CGAffineTransform(translationX: 0, y: 400)
            self.bg.alpha = 0
        }, completion: { _ in
            self.dismiss(animated: false)
        })
    }
}




