import UIKit
import QuickLook

class PreviewViewController: UIViewController, QLPreviewingController {

    // MARK: - Types

    /// Represents the type of .honeydue package
    private enum PackageType {
        case contractor
        case residence
    }

    // MARK: - UI Elements

    private let containerView: UIView = {
        let view = UIView()
        view.translatesAutoresizingMaskIntoConstraints = false
        return view
    }()

    private let iconImageView: UIImageView = {
        let imageView = UIImageView()
        imageView.translatesAutoresizingMaskIntoConstraints = false
        imageView.contentMode = .scaleAspectFit
        imageView.tintColor = UIColor(red: 7/255, green: 160/255, blue: 195/255, alpha: 1) // App primary color
        let config = UIImage.SymbolConfiguration(pointSize: 60, weight: .light)
        imageView.image = UIImage(systemName: "person.crop.rectangle.stack", withConfiguration: config)
        return imageView
    }()

    private let titleLabel: UILabel = {
        let label = UILabel()
        label.translatesAutoresizingMaskIntoConstraints = false
        label.font = .systemFont(ofSize: 24, weight: .bold)
        label.textColor = .label
        label.textAlignment = .center
        label.numberOfLines = 2
        return label
    }()

    private let subtitleLabel: UILabel = {
        let label = UILabel()
        label.translatesAutoresizingMaskIntoConstraints = false
        label.font = .systemFont(ofSize: 15, weight: .medium)
        label.textColor = .secondaryLabel
        label.textAlignment = .center
        label.text = "honeyDue Contractor File"
        return label
    }()

    private let dividerView: UIView = {
        let view = UIView()
        view.translatesAutoresizingMaskIntoConstraints = false
        view.backgroundColor = .separator
        return view
    }()

    private let detailsStackView: UIStackView = {
        let stack = UIStackView()
        stack.translatesAutoresizingMaskIntoConstraints = false
        stack.axis = .vertical
        stack.spacing = 12
        stack.alignment = .leading
        return stack
    }()

    private let instructionCard: UIView = {
        let view = UIView()
        view.translatesAutoresizingMaskIntoConstraints = false
        view.backgroundColor = UIColor(red: 7/255, green: 160/255, blue: 195/255, alpha: 0.1)
        view.layer.cornerRadius = 12
        return view
    }()

    private let instructionLabel: UILabel = {
        let label = UILabel()
        label.translatesAutoresizingMaskIntoConstraints = false
        label.font = .systemFont(ofSize: 15, weight: .medium)
        label.textColor = UIColor(red: 7/255, green: 160/255, blue: 195/255, alpha: 1)
        label.textAlignment = .center
        label.numberOfLines = 0
        label.text = "Tap the share button below, then select \"honeyDue\" to import this contractor."
        return label
    }()

    private let arrowImageView: UIImageView = {
        let imageView = UIImageView()
        imageView.translatesAutoresizingMaskIntoConstraints = false
        imageView.contentMode = .scaleAspectFit
        imageView.tintColor = .secondaryLabel
        let config = UIImage.SymbolConfiguration(pointSize: 24, weight: .medium)
        imageView.image = UIImage(systemName: "arrow.down", withConfiguration: config)
        return imageView
    }()

    // MARK: - Data

    private var contractorData: ContractorPreviewData?
    private var residenceData: ResidencePreviewData?
    private var currentPackageType: PackageType = .contractor

    // MARK: - Lifecycle

    override func viewDidLoad() {
        super.viewDidLoad()
        print("honeyDueQLPreview: viewDidLoad called")
        setupUI()
    }

    // MARK: - Setup

    private func setupUI() {
        view.backgroundColor = .systemBackground

        view.addSubview(containerView)
        containerView.addSubview(iconImageView)
        containerView.addSubview(titleLabel)
        containerView.addSubview(subtitleLabel)
        containerView.addSubview(dividerView)
        containerView.addSubview(detailsStackView)
        containerView.addSubview(instructionCard)
        instructionCard.addSubview(instructionLabel)
        containerView.addSubview(arrowImageView)

        NSLayoutConstraint.activate([
            containerView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            containerView.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: -40),
            containerView.leadingAnchor.constraint(greaterThanOrEqualTo: view.leadingAnchor, constant: 32),
            containerView.trailingAnchor.constraint(lessThanOrEqualTo: view.trailingAnchor, constant: -32),
            containerView.widthAnchor.constraint(lessThanOrEqualToConstant: 340),

            iconImageView.topAnchor.constraint(equalTo: containerView.topAnchor),
            iconImageView.centerXAnchor.constraint(equalTo: containerView.centerXAnchor),
            iconImageView.widthAnchor.constraint(equalToConstant: 80),
            iconImageView.heightAnchor.constraint(equalToConstant: 80),

            titleLabel.topAnchor.constraint(equalTo: iconImageView.bottomAnchor, constant: 16),
            titleLabel.leadingAnchor.constraint(equalTo: containerView.leadingAnchor),
            titleLabel.trailingAnchor.constraint(equalTo: containerView.trailingAnchor),

            subtitleLabel.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 4),
            subtitleLabel.leadingAnchor.constraint(equalTo: containerView.leadingAnchor),
            subtitleLabel.trailingAnchor.constraint(equalTo: containerView.trailingAnchor),

            dividerView.topAnchor.constraint(equalTo: subtitleLabel.bottomAnchor, constant: 20),
            dividerView.leadingAnchor.constraint(equalTo: containerView.leadingAnchor),
            dividerView.trailingAnchor.constraint(equalTo: containerView.trailingAnchor),
            dividerView.heightAnchor.constraint(equalToConstant: 1),

            detailsStackView.topAnchor.constraint(equalTo: dividerView.bottomAnchor, constant: 20),
            detailsStackView.leadingAnchor.constraint(equalTo: containerView.leadingAnchor),
            detailsStackView.trailingAnchor.constraint(equalTo: containerView.trailingAnchor),

            instructionCard.topAnchor.constraint(equalTo: detailsStackView.bottomAnchor, constant: 24),
            instructionCard.leadingAnchor.constraint(equalTo: containerView.leadingAnchor),
            instructionCard.trailingAnchor.constraint(equalTo: containerView.trailingAnchor),

            instructionLabel.topAnchor.constraint(equalTo: instructionCard.topAnchor, constant: 16),
            instructionLabel.leadingAnchor.constraint(equalTo: instructionCard.leadingAnchor, constant: 16),
            instructionLabel.trailingAnchor.constraint(equalTo: instructionCard.trailingAnchor, constant: -16),
            instructionLabel.bottomAnchor.constraint(equalTo: instructionCard.bottomAnchor, constant: -16),

            arrowImageView.topAnchor.constraint(equalTo: instructionCard.bottomAnchor, constant: 16),
            arrowImageView.centerXAnchor.constraint(equalTo: containerView.centerXAnchor),
            arrowImageView.bottomAnchor.constraint(equalTo: containerView.bottomAnchor),
        ])
    }

    private func addDetailRow(icon: String, text: String) {
        let rowStack = UIStackView()
        rowStack.axis = .horizontal
        rowStack.spacing = 12
        rowStack.alignment = .center

        let iconView = UIImageView()
        iconView.translatesAutoresizingMaskIntoConstraints = false
        let config = UIImage.SymbolConfiguration(pointSize: 16, weight: .medium)
        iconView.image = UIImage(systemName: icon, withConfiguration: config)
        iconView.tintColor = .secondaryLabel
        iconView.widthAnchor.constraint(equalToConstant: 24).isActive = true
        iconView.heightAnchor.constraint(equalToConstant: 24).isActive = true

        let textLabel = UILabel()
        textLabel.font = .systemFont(ofSize: 15)
        textLabel.textColor = .label
        textLabel.text = text
        textLabel.numberOfLines = 1

        rowStack.addArrangedSubview(iconView)
        rowStack.addArrangedSubview(textLabel)

        detailsStackView.addArrangedSubview(rowStack)
    }

    // MARK: - QLPreviewingController

    func preparePreviewOfFile(at url: URL) async throws {
        print("honeyDueQLPreview: preparePreviewOfFile called with URL: \(url)")

        // Parse the .honeydue file — single Codable pass to detect type, then decode
        let data = try Data(contentsOf: url)
        let decoder = JSONDecoder()

        let envelope = try? decoder.decode(PackageTypeEnvelope.self, from: data)

        if envelope?.type == "residence" {
            currentPackageType = .residence

            let residence = try decoder.decode(ResidencePreviewData.self, from: data)
            self.residenceData = residence
            print("honeyDueQLPreview: Parsed residence: \(residence.residenceName)")

            await MainActor.run {
                self.updateUIForResidence(with: residence)
            }
        } else {
            currentPackageType = .contractor

            let contractor = try decoder.decode(ContractorPreviewData.self, from: data)
            self.contractorData = contractor
            print("honeyDueQLPreview: Parsed contractor: \(contractor.name)")

            await MainActor.run {
                self.updateUIForContractor(with: contractor)
            }
        }
    }

    private func updateUIForContractor(with contractor: ContractorPreviewData) {
        // Update icon
        let config = UIImage.SymbolConfiguration(pointSize: 60, weight: .light)
        iconImageView.image = UIImage(systemName: "person.crop.rectangle.stack", withConfiguration: config)

        titleLabel.text = contractor.name
        subtitleLabel.text = "honeyDue Contractor File"
        instructionLabel.text = "Tap the share button below, then select \"honeyDue\" to import this contractor."

        // Clear existing details
        detailsStackView.arrangedSubviews.forEach { $0.removeFromSuperview() }

        // Add details
        if let company = contractor.company, !company.isEmpty {
            addDetailRow(icon: "building.2", text: company)
        }

        if let phone = contractor.phone, !phone.isEmpty {
            addDetailRow(icon: "phone", text: phone)
        }

        if let email = contractor.email, !email.isEmpty {
            addDetailRow(icon: "envelope", text: email)
        }

        if !contractor.specialtyNames.isEmpty {
            let specialties = contractor.specialtyNames.joined(separator: ", ")
            addDetailRow(icon: "wrench.and.screwdriver", text: specialties)
        }

        if let exportedBy = contractor.exportedBy, !exportedBy.isEmpty {
            addDetailRow(icon: "person", text: "Shared by \(exportedBy)")
        }
    }

    private func updateUIForResidence(with residence: ResidencePreviewData) {
        // Update icon
        let config = UIImage.SymbolConfiguration(pointSize: 60, weight: .light)
        iconImageView.image = UIImage(systemName: "house.fill", withConfiguration: config)

        titleLabel.text = residence.residenceName
        subtitleLabel.text = "honeyDue Residence Invite"
        instructionLabel.text = "Tap the share button below, then select \"honeyDue\" to join this residence."

        // Clear existing details
        detailsStackView.arrangedSubviews.forEach { $0.removeFromSuperview() }

        // Add details
        if let sharedBy = residence.sharedBy, !sharedBy.isEmpty {
            addDetailRow(icon: "person", text: "Shared by \(sharedBy)")
        }

        if let expiresAt = residence.expiresAt, !expiresAt.isEmpty {
            addDetailRow(icon: "clock", text: "Expires: \(expiresAt)")
        }
    }
}

// MARK: - Type Discriminator

/// Lightweight struct to detect the package type without a full parse
private struct PackageTypeEnvelope: Decodable {
    let type: String?
}

// MARK: - Data Model

struct ContractorPreviewData: Codable {
    let version: Int
    let name: String
    let company: String?
    let phone: String?
    let email: String?
    let website: String?
    let notes: String?
    let streetAddress: String?
    let city: String?
    let stateProvince: String?
    let postalCode: String?
    let specialtyNames: [String]
    let rating: Double?
    let isFavorite: Bool
    let exportedAt: String?
    let exportedBy: String?

    enum CodingKeys: String, CodingKey {
        case version, name, company, phone, email, website, notes
        case streetAddress = "street_address"
        case city
        case stateProvince = "state_province"
        case postalCode = "postal_code"
        case specialtyNames = "specialty_names"
        case rating
        case isFavorite = "is_favorite"
        case exportedAt = "exported_at"
        case exportedBy = "exported_by"
    }
}

struct ResidencePreviewData: Codable {
    let version: Int
    let type: String
    let shareCode: String
    let residenceName: String
    let sharedBy: String?
    let expiresAt: String?
    let exportedAt: String?
    let exportedBy: String?

    enum CodingKeys: String, CodingKey {
        case version, type
        case shareCode = "share_code"
        case residenceName = "residence_name"
        case sharedBy = "shared_by"
        case expiresAt = "expires_at"
        case exportedAt = "exported_at"
        case exportedBy = "exported_by"
    }
}
