"use client";

import { Twitter, Linkedin, Facebook, Instagram, Heart, MessageCircle, Repeat2, Share, ThumbsUp, Send } from "lucide-react";
import type { Network } from "@/lib/types";
import { countTwitterChars } from "@/lib/twitter-text";

const CHAR_LIMITS: Record<Network, number> = {
  TWITTER: 280,
  LINKEDIN: 3000,
  FACEBOOK: 63206,
  INSTAGRAM: 2200,
};

const NETWORK_CONFIG: Record<Network, { name: string; icon: typeof Twitter; color: string; bgColor: string }> = {
  TWITTER: { name: "Twitter / X", icon: Twitter, color: "#1DA1F2", bgColor: "bg-[#f7f9fa]" },
  LINKEDIN: { name: "LinkedIn", icon: Linkedin, color: "#0A66C2", bgColor: "bg-[#f3f6f8]" },
  FACEBOOK: { name: "Facebook", icon: Facebook, color: "#1877F2", bgColor: "bg-[#f0f2f5]" },
  INSTAGRAM: { name: "Instagram", icon: Instagram, color: "#E4405F", bgColor: "bg-white" },
};

interface PostPreviewProps {
  content: string;
  networks: Network[];
  files?: File[];
}

function CharLimitBar({ content, limit, network }: { content: string; limit: number; network: Network }) {
  const charCount = network === "TWITTER" ? countTwitterChars(content) : content.length;
  const pct = (charCount / limit) * 100;
  const overLimit = charCount > limit;
  const nearLimit = pct >= 80;

  return (
    <div className="flex items-center gap-2 text-xs">
      <div className="flex-1 h-1.5 rounded-full bg-gray-200 overflow-hidden">
        <div
          className={`h-full rounded-full transition-all ${
            overLimit ? "bg-red-500" : nearLimit ? "bg-yellow-500" : "bg-green-500"
          }`}
          style={{ width: `${Math.min(pct, 100)}%` }}
        />
      </div>
      <span className={`tabular-nums ${overLimit ? "text-red-600 font-medium" : nearLimit ? "text-yellow-600" : "text-gray-400"}`}>
        {charCount}/{limit}
      </span>
    </div>
  );
}

function truncateContent(text: string, limit: number): { display: string; truncated: boolean } {
  if (text.length <= limit) return { display: text, truncated: false };
  return { display: text.slice(0, limit) + "...", truncated: true };
}

function TwitterPreview({ content, files }: { content: string; files?: File[] }) {
  const threads = countTwitterChars(content) > 280
    ? content.match(/.{1,280}(?:\s|$)/g) || [content]
    : [content];
  const isThread = threads.length > 1;

  return (
    <div className="space-y-2">
      {threads.map((chunk, i) => (
        <div key={i} className="rounded-xl border border-gray-200 bg-white p-3">
          <div className="flex gap-2.5">
            <div className="h-10 w-10 shrink-0 rounded-full bg-gray-300" />
            <div className="flex-1 min-w-0">
              <div className="flex items-center gap-1">
                <span className="text-sm font-bold text-gray-900">PingCAP</span>
                <span className="text-sm text-gray-500">@PingCAP</span>
                {isThread && (
                  <span className="ml-auto text-[10px] text-blue-500 font-medium">
                    {i + 1}/{threads.length}
                  </span>
                )}
              </div>
              <p className="text-sm text-gray-900 whitespace-pre-wrap mt-0.5">{chunk.trim()}</p>
              {i === 0 && files && files.length > 0 && (
                <MediaThumbs files={files} />
              )}
              <div className="flex items-center gap-6 mt-2 text-gray-400">
                <MessageCircle className="h-3.5 w-3.5" />
                <Repeat2 className="h-3.5 w-3.5" />
                <Heart className="h-3.5 w-3.5" />
                <Share className="h-3.5 w-3.5" />
              </div>
            </div>
          </div>
        </div>
      ))}
      {isThread && (
        <p className="text-[10px] text-blue-500 text-center font-medium">
          Thread: {threads.length} tweets
        </p>
      )}
    </div>
  );
}

function LinkedInPreview({ content, files }: { content: string; files?: File[] }) {
  const { display, truncated } = truncateContent(content, 210);
  return (
    <div className="rounded-lg border border-gray-200 bg-white overflow-hidden">
      <div className="border-b-2 border-[#0A66C2]" />
      <div className="p-3">
        <div className="flex gap-2.5">
          <div className="h-10 w-10 shrink-0 rounded-full bg-gray-300" />
          <div>
            <p className="text-sm font-semibold text-gray-900">PingCAP</p>
            <p className="text-[11px] text-gray-500">1,234 followers</p>
          </div>
        </div>
        <p className="text-sm text-gray-900 whitespace-pre-wrap mt-2.5">
          {display}
          {truncated && <span className="text-gray-500 text-xs"> ...see more</span>}
        </p>
        {files && files.length > 0 && <MediaThumbs files={files} />}
        <div className="flex items-center gap-4 mt-2.5 pt-2 border-t text-gray-500 text-xs">
          <span className="flex items-center gap-1"><ThumbsUp className="h-3.5 w-3.5" /> Like</span>
          <span className="flex items-center gap-1"><MessageCircle className="h-3.5 w-3.5" /> Comment</span>
          <span className="flex items-center gap-1"><Repeat2 className="h-3.5 w-3.5" /> Repost</span>
          <span className="flex items-center gap-1"><Send className="h-3.5 w-3.5" /> Send</span>
        </div>
      </div>
    </div>
  );
}

function FacebookPreview({ content, files }: { content: string; files?: File[] }) {
  const { display, truncated } = truncateContent(content, 300);
  return (
    <div className="rounded-lg border border-gray-200 bg-white p-3">
      <div className="flex gap-2.5">
        <div className="h-10 w-10 shrink-0 rounded-full bg-gray-300" />
        <div>
          <p className="text-sm font-semibold text-gray-900">PingCAP</p>
          <p className="text-[11px] text-gray-500">Just now · Public</p>
        </div>
      </div>
      <p className="text-sm text-gray-900 whitespace-pre-wrap mt-2.5">
        {display}
        {truncated && <span className="text-gray-500 text-xs"> ...See more</span>}
      </p>
      {files && files.length > 0 && <MediaThumbs files={files} />}
      <div className="flex items-center justify-between mt-2.5 pt-2 border-t text-gray-500 text-xs">
        <span className="flex items-center gap-1"><ThumbsUp className="h-3.5 w-3.5" /> Like</span>
        <span className="flex items-center gap-1"><MessageCircle className="h-3.5 w-3.5" /> Comment</span>
        <span className="flex items-center gap-1"><Share className="h-3.5 w-3.5" /> Share</span>
      </div>
    </div>
  );
}

function InstagramPreview({ content, files }: { content: string; files?: File[] }) {
  const { display, truncated } = truncateContent(content, 150);
  return (
    <div className="rounded-lg border border-gray-200 bg-white overflow-hidden">
      <div className="flex items-center gap-2.5 p-3 border-b">
        <div className="h-8 w-8 rounded-full bg-gradient-to-tr from-yellow-400 via-pink-500 to-purple-600 p-0.5">
          <div className="h-full w-full rounded-full bg-gray-300" />
        </div>
        <span className="text-sm font-semibold text-gray-900">pingcap</span>
      </div>
      {files && files.length > 0 ? (
        <MediaThumbs files={files} square />
      ) : (
        <div className="h-48 bg-gray-100 flex items-center justify-center">
          <Instagram className="h-8 w-8 text-gray-300" />
        </div>
      )}
      <div className="p-3">
        <div className="flex items-center gap-3 text-gray-900 mb-2">
          <Heart className="h-5 w-5" />
          <MessageCircle className="h-5 w-5" />
          <Send className="h-5 w-5" />
        </div>
        <p className="text-sm">
          <span className="font-semibold">pingcap</span>{" "}
          {display}
          {truncated && <span className="text-gray-500 text-xs"> ...more</span>}
        </p>
      </div>
    </div>
  );
}

function MediaItem({ file, className }: { file: File; className?: string }) {
  if (file.type.startsWith("video/") || file.type === "video/quicktime") {
    return (
      <div className={`relative bg-gray-900 flex items-center justify-center ${className ?? ""}`}>
        <div className="absolute inset-0 flex items-center justify-center">
          <div className="h-10 w-10 rounded-full bg-white/80 flex items-center justify-center">
            <div className="ml-0.5 w-0 h-0 border-l-[12px] border-l-gray-900 border-y-[7px] border-y-transparent" />
          </div>
        </div>
        <span className="absolute bottom-1 right-1 bg-black/70 text-white text-[10px] px-1.5 py-0.5 rounded">VIDEO</span>
      </div>
    );
  }

  if (file.type === "image/gif") {
    return (
      <div className={`relative bg-gray-100 ${className ?? ""}`}>
        {/* eslint-disable-next-line @next/next/no-img-element */}
        <img src={URL.createObjectURL(file)} alt="" className="h-full w-full object-contain" />
        <span className="absolute bottom-1 left-1 bg-black/70 text-white text-[10px] px-1.5 py-0.5 rounded font-bold">GIF</span>
      </div>
    );
  }

  return (
    <div className={`bg-gray-100 ${className ?? ""}`}>
      {/* eslint-disable-next-line @next/next/no-img-element */}
      <img src={URL.createObjectURL(file)} alt="" className="h-full w-full object-contain" />
    </div>
  );
}

function MediaThumbs({ files, square }: { files: File[]; square?: boolean }) {
  const count = Math.min(files.length, 4);

  if (count === 0) return null;

  // Single media
  if (count === 1) {
    return (
      <div className="mt-2 rounded-lg overflow-hidden">
        <MediaItem
          file={files[0]}
          className={square ? "aspect-square" : "aspect-video"}
        />
      </div>
    );
  }

  // 2 images: side by side
  if (count === 2) {
    return (
      <div className="mt-2 grid grid-cols-2 gap-0.5 rounded-lg overflow-hidden">
        {files.slice(0, 2).map((file, i) => (
          <MediaItem key={i} file={file} className={square ? "aspect-square" : "aspect-video"} />
        ))}
      </div>
    );
  }

  // 3 images: 1 large left + 2 stacked right (Twitter layout)
  if (count === 3) {
    return (
      <div className="mt-2 grid grid-cols-2 gap-0.5 rounded-lg overflow-hidden" style={{ height: "220px" }}>
        <MediaItem file={files[0]} className="row-span-2 h-full" />
        <div className="flex flex-col gap-0.5 h-full">
          <MediaItem file={files[1]} className="flex-1 min-h-0" />
          <MediaItem file={files[2]} className="flex-1 min-h-0" />
        </div>
      </div>
    );
  }

  // 4 images: 2x2 grid
  return (
    <div className="mt-2 grid grid-cols-2 gap-0.5 rounded-lg overflow-hidden">
      {files.slice(0, 4).map((file, i) => (
        <MediaItem key={i} file={file} className={square ? "aspect-square" : "aspect-[4/3]"} />
      ))}
    </div>
  );
}

const PREVIEW_COMPONENTS: Record<Network, React.ComponentType<{ content: string; files?: File[] }>> = {
  TWITTER: TwitterPreview,
  LINKEDIN: LinkedInPreview,
  FACEBOOK: FacebookPreview,
  INSTAGRAM: InstagramPreview,
};

export function PostPreview({ content, networks, files }: PostPreviewProps) {
  if (networks.length === 0) {
    return (
      <div className="flex flex-col items-center justify-center py-8 text-center">
        <p className="text-sm text-gray-400">Select a network to see the preview</p>
      </div>
    );
  }

  if (!content.trim()) {
    return (
      <div className="flex flex-col items-center justify-center py-8 text-center">
        <p className="text-sm text-gray-400">Start typing to see a preview</p>
      </div>
    );
  }

  return (
    <div className="space-y-4">
      {networks.map((network) => {
        const config = NETWORK_CONFIG[network];
        const Icon = config.icon;
        const Preview = PREVIEW_COMPONENTS[network];
        const limit = CHAR_LIMITS[network];

        return (
          <div key={network} className="space-y-2">
            <div className="flex items-center gap-1.5">
              <Icon className="h-3.5 w-3.5" style={{ color: config.color }} />
              <span className="text-xs font-medium text-gray-600">{config.name}</span>
            </div>
            <CharLimitBar content={content} limit={limit} network={network} />
            <div className={`${config.bgColor} rounded-lg p-2`}>
              <Preview content={content} files={files} />
            </div>
          </div>
        );
      })}
    </div>
  );
}
