import SwiftUI
import UIKit
import UniformTypeIdentifiers

struct ContentView: View {
  @State private var gifs: [GIF] = []
  @State private var showingAddGIF = false
  @State private var showingAlert = false
  @State private var alertTitle = ""
  @State private var alertMessage = ""

  // For handling app lifecycle notifications
  @Environment(\.scenePhase) private var scenePhase

  var body: some View {
    NavigationView {
      ZStack {
        if gifs.isEmpty {
          VStack {
            Text("No GIFs saved")
              .font(.headline)
            Text("Add your first GIF using the + button")
              .font(.subheadline)
              .foregroundColor(.secondary)
          }
        } else {
          ScrollView {
            LazyVGrid(
              columns: [
                GridItem(.flexible(), spacing: 10),
                GridItem(.flexible(), spacing: 10),
              ], spacing: 10
            ) {
              ForEach(gifs) { gif in
                GIFCell(
                  gif: gif,
                  onTap: {
                    copyGIFToClipboard(gif)
                  },
                  onDelete: {
                    deleteGIF(gif)
                  })
              }
            }
            .padding()
          }
        }
      }
      .navigationTitle("GIF Collector")
      .toolbar {
        Button(action: {
          showingAddGIF = true
        }) {
          Image(systemName: "plus.circle.fill")
            .resizable()
            .frame(width: 24, height: 24)
        }
      }
      .sheet(isPresented: $showingAddGIF) {
        AddGIFView { urlString, gifData in
          saveGIF(urlString: urlString, data: gifData)
          showingAddGIF = false
        } onCancel: {
          showingAddGIF = false
        }
      }
      .alert(isPresented: $showingAlert) {
        Alert(
          title: Text(alertTitle), message: Text(alertMessage), dismissButton: .default(Text("OK")))
      }
      .onAppear {
        loadGIFs()

        // Register for foreground notification
        NotificationCenter.default.addObserver(
          forName: UIApplication.willEnterForegroundNotification,
          object: nil,
          queue: .main
        ) { _ in
          loadGIFs()
        }
      }
      .onDisappear {
        // Remove notification observer when view disappears
        NotificationCenter.default.removeObserver(
          self,
          name: UIApplication.willEnterForegroundNotification,
          object: nil
        )
      }
      // Also monitor scene phase changes
      .onChange(of: scenePhase) { newPhase in
        if newPhase == .active {
          loadGIFs()
        }
      }
    }
  }

  private func loadGIFs() {
    // Check for shared GIFs on app launch
    GIFStorageService.shared.checkForSharedGIFs()
    gifs = GIFStorageService.shared.fetchGIFs()
  }

  private func saveGIF(urlString: String, data: Data) {
    GIFStorageService.shared.saveGIF(data: data, fromURL: urlString) { _ in
      loadGIFs()
    }
  }

  private func deleteGIF(_ gif: GIF) {
    print("Got delete request for \(gif.id)")
    GIFStorageService.shared.deleteGIF(with: gif.id)
    loadGIFs()
  }

  private func copyGIFToClipboard(_ gif: GIF) {
    guard let data = GIFStorageService.shared.getGIFData(for: gif) else {
      showAlert(title: "Error", message: "Could not load GIF data")
      return
    }

    let pasteboard = UIPasteboard.general
    pasteboard.setData(data, forPasteboardType: UTType.gif.identifier)

    showAlert(title: "Copied!", message: "GIF copied to clipboard")
  }

  private func showAlert(title: String, message: String) {
    alertTitle = title
    alertMessage = message
    showingAlert = true
  }
}

struct GIFCell: View {
  let gif: GIF
  let onTap: () -> Void
  let onDelete: () -> Void

  @State private var showingDeleteConfirmation = false

  var body: some View {
    ZStack {
      GIFPlayerUIView(filePath: gif.localFilePath)
        .aspectRatio(1, contentMode: .fill)
        .cornerRadius(8)

      // Tap hint overlay
      Color.black.opacity(0.0001)  // Almost transparent for hit testing
    }
    .aspectRatio(1, contentMode: .fit)
    .cornerRadius(8)
    .clipped()
    .shadow(radius: 2)
    .onTapGesture {
      onTap()
    }
    .contextMenu {
      Button(
        role: .destructive,
        action: {
          onDelete()
        }
      ) {
        Label("Delete", systemImage: "trash")
      }

      Button(action: {
        onTap()
      }) {
        Label("Copy to Clipboard", systemImage: "doc.on.clipboard")
      }
    }
  }
}

struct GIFPlayerUIView: UIViewRepresentable {
  let filePath: String

  func makeUIView(context: Context) -> UIView {
    let view = UIView()
    let gifPlayerView = GIFPlayerView(frame: view.bounds)
    gifPlayerView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
    view.addSubview(gifPlayerView)

    if let data = try? Data(contentsOf: URL(fileURLWithPath: filePath)) {
      gifPlayerView.loadGIF(from: data)
      gifPlayerView.startAnimating()
    }

    return view
  }

  func updateUIView(_ uiView: UIView, context: Context) {
    // Nothing to update
  }
}

struct AddGIFView: View {
  @State private var urlString = ""
  @State private var isLoading = false
  @State private var previewData: Data?
  @State private var showError = false
  @State private var errorMessage = ""

  let onSave: (String, Data) -> Void
  let onCancel: () -> Void

  var body: some View {
    NavigationView {
      VStack(spacing: 20) {
        TextField("Enter GIF URL", text: $urlString)
          .textFieldStyle(RoundedBorderTextFieldStyle())
          .autocapitalization(.none)
          .disableAutocorrection(true)
          .onChange(of: urlString) { _ in
            if !urlString.isEmpty {
              loadPreview()
            } else {
              previewData = nil
            }
          }

        if isLoading {
          ProgressView()
            .frame(height: 200)
        } else if let data = previewData {
          GIFPreview(data: data)
            .frame(height: 200)
            .cornerRadius(8)
        } else {
          Rectangle()
            .fill(Color.gray.opacity(0.2))
            .frame(height: 200)
            .cornerRadius(8)
            .overlay(
              Text("GIF Preview")
                .foregroundColor(.gray)
            )
        }

        Spacer()
      }
      .padding()
      .navigationTitle("Add New GIF")
      .navigationBarItems(
        leading: Button("Cancel") {
          onCancel()
        },
        trailing: Button("Save") {
          if let data = previewData {
            onSave(urlString, data)
          }
        }
        .disabled(previewData == nil)
      )
      .alert(isPresented: $showError) {
        Alert(
          title: Text("Error"), message: Text(errorMessage), dismissButton: .default(Text("OK")))
      }
    }
  }

  private func loadPreview() {
    guard URL(string: urlString) != nil else {
      return
    }

    isLoading = true
    previewData = nil

    DownloadService.shared.downloadGIF(from: urlString) { data, error in
      isLoading = false

      if let error = error {
        errorMessage = error.localizedDescription
        showError = true
        return
      }

      if let data = data {
        previewData = data
      } else {
        errorMessage = "Failed to load GIF"
        showError = true
      }
    }
  }
}

struct GIFPreview: UIViewRepresentable {
  let data: Data

  func makeUIView(context: Context) -> UIView {
    let view = UIView()
    let gifPlayerView = GIFPlayerView(frame: view.bounds)
    gifPlayerView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
    view.addSubview(gifPlayerView)

    gifPlayerView.loadGIF(from: data)
    gifPlayerView.startAnimating()

    return view
  }

  func updateUIView(_ uiView: UIView, context: Context) {
    // Nothing to update
  }
}

#Preview {
  ContentView()
}
