'use client';

import { useEffect, useMemo, useState } from 'react';
import { Check, Copy, Search, Send } from 'lucide-react';
import { useAuth } from '@/lib/hooks/useAuth';
import {
  organizationApi,
  type CounterpartItemDto,
  type CounterpartSearchResultDto,
} from '@/lib/api/organization';
import { Button } from '@/components/ui/common/Button';
import { Input } from '@/components/ui/common/Input';
import type { ApiError } from '@/types/api';

type StoredInviteLink = {
  invitationId: string;
  ownerEmail: string;
  invitationUrl: string;
};

function inviteLinksStorageKey(orgId: string): string {
  return `counterpartInviteLinks:${orgId}`;
}

function readStoredInviteLinks(orgId: string): Record<string, StoredInviteLink> {
  if (typeof window === 'undefined') return {};
  try {
    const raw = window.localStorage.getItem(inviteLinksStorageKey(orgId));
    if (!raw) return {};
    const parsed = JSON.parse(raw) as Record<string, StoredInviteLink>;
    return parsed && typeof parsed === 'object' ? parsed : {};
  } catch {
    return {};
  }
}

function writeStoredInviteLinks(orgId: string, links: Record<string, StoredInviteLink>) {
  if (typeof window === 'undefined') return;
  window.localStorage.setItem(inviteLinksStorageKey(orgId), JSON.stringify(links));
}

function formatApiMessage(err: unknown): string {
  if (!err || typeof err !== 'object') return 'Something went wrong';
  const m = (err as ApiError).message;
  if (Array.isArray(m)) return m.join(', ');
  if (typeof m === 'string') return m;
  return 'Something went wrong';
}

export default function OrganizationsPage() {
  const { currentOrganization } = useAuth();
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState('');
  const [success, setSuccess] = useState('');

  const [searchTerm, setSearchTerm] = useState('');
  const [searchLoading, setSearchLoading] = useState(false);
  const [results, setResults] = useState<CounterpartSearchResultDto[]>([]);
  const [selectedOrgId, setSelectedOrgId] = useState<string | null>(null);
  const [linkLoading, setLinkLoading] = useState(false);

  const [items, setItems] = useState<CounterpartItemDto[]>([]);
  const [manualOrganizationName, setManualOrganizationName] = useState('');
  const [manualOwnerEmail, setManualOwnerEmail] = useState('');
  const [manualPhone, setManualPhone] = useState('');
  const [inviteLoading, setInviteLoading] = useState(false);
  const [copiedId, setCopiedId] = useState<string | null>(null);
  const [pendingInviteLinks, setPendingInviteLinks] = useState<Record<string, StoredInviteLink>>({});

  const counterpartLabel = currentOrganization?.type === 'LAB' ? 'Clinic' : 'Lab';
  const tabLabel = currentOrganization?.type === 'LAB' ? 'Clinics' : 'Labs';

  const selectedResult = useMemo(
    () => results.find((r) => r.id === selectedOrgId) ?? null,
    [results, selectedOrgId],
  );

  async function loadList() {
    setLoading(true);
    setError('');
    try {
      const res = await organizationApi.list();
      setItems(res.data.items);
    } catch (e) {
      setError(formatApiMessage(e));
    } finally {
      setLoading(false);
    }
  }

  useEffect(() => {
    if (!currentOrganization?.id) return;
    setPendingInviteLinks(readStoredInviteLinks(currentOrganization.id));
  }, [currentOrganization?.id]);

  useEffect(() => {
    void loadList();
  }, []);

  useEffect(() => {
    if (!success) return;
    const t = setTimeout(() => setSuccess(''), 4000);
    return () => clearTimeout(t);
  }, [success]);

  async function runSearch() {
    setSearchLoading(true);
    setError('');
    setSelectedOrgId(null);
    try {
      const res = await organizationApi.search(searchTerm.trim());
      setResults(res.data);
    } catch (e) {
      setError(formatApiMessage(e));
    } finally {
      setSearchLoading(false);
    }
  }

  async function createLink() {
    if (!selectedOrgId) return;
    setLinkLoading(true);
    setError('');
    try {
      await organizationApi.createLink(selectedOrgId);
      setSuccess(`${counterpartLabel} link request created`);
      setResults([]);
      setSelectedOrgId(null);
      setSearchTerm('');
      await loadList();
    } catch (e) {
      setError(formatApiMessage(e));
    } finally {
      setLinkLoading(false);
    }
  }

  async function sendInvite() {
    setInviteLoading(true);
    setError('');
    try {
      const res = await organizationApi.invite({
        organizationName: manualOrganizationName.trim(),
        ownerEmail: manualOwnerEmail.trim(),
        phone: manualPhone.trim() || undefined,
      });
      if (currentOrganization?.id) {
        const nextLinks = {
          ...pendingInviteLinks,
          [res.data.invitationId]: {
            invitationId: res.data.invitationId,
            ownerEmail: manualOwnerEmail.trim().toLowerCase(),
            invitationUrl: res.data.invitationUrl,
          },
        };
        setPendingInviteLinks(nextLinks);
        writeStoredInviteLinks(currentOrganization.id, nextLinks);
      }
      setSuccess(`Invitation link created for ${manualOwnerEmail.trim()}`);
      setManualOrganizationName('');
      setManualOwnerEmail('');
      setManualPhone('');
      await loadList();
    } catch (e) {
      setError(formatApiMessage(e));
    } finally {
      setInviteLoading(false);
    }
  }

  if (!currentOrganization) {
    return <p className="text-sm text-text-secondary">Loading organization...</p>;
  }

  return (
    <div className="space-y-6">
      <div>
        <h1 className="text-2xl font-semibold text-text-primary">{tabLabel}</h1>
        <p className="text-sm text-text-secondary mt-1">
          Search subscribed {tabLabel.toLowerCase()}, request link access, or invite a new{' '}
          {counterpartLabel.toLowerCase()} owner.
        </p>
      </div>

      {error && (
        <div className="rounded-[var(--radius-md)] border border-red-500/40 bg-red-500/10 px-4 py-3 text-sm text-red-700 dark:text-red-300">
          {error}
        </div>
      )}
      {success && (
        <div className="rounded-[var(--radius-md)] border border-primary/30 bg-primary-soft/40 px-4 py-3 text-sm text-text-primary">
          {success}
        </div>
      )}

      <div className="rounded-[var(--radius-md)] border border-border/70 p-4 space-y-3">
        <h2 className="text-base font-semibold text-text-primary">Search existing {tabLabel}</h2>
        <div className="flex gap-2">
          <Input
            value={searchTerm}
            onChange={(e) => setSearchTerm(e.target.value)}
            placeholder={`Search by ${counterpartLabel.toLowerCase()} name, email, or phone`}
          />
          <Button type="button" isLoading={searchLoading} onClick={() => void runSearch()}>
            <Search className="w-4 h-4 mr-2" />
            Search
          </Button>
        </div>

        {results.length > 0 && (
          <div className="space-y-2 pt-1">
            {results.map((r) => (
              <button
                key={r.id}
                type="button"
                onClick={() => setSelectedOrgId(r.id)}
                className={`w-full text-left rounded-[var(--radius-md)] border px-3 py-2 ${
                  selectedOrgId === r.id
                    ? 'border-primary/70 bg-primary-soft/30'
                    : 'border-border/60 hover:border-border-strong'
                }`}
              >
                <p className="text-sm font-medium text-text-primary">{r.name}</p>
                <p className="text-xs text-text-secondary mt-0.5">
                  {r.email}
                  {r.phone ? ` - ${r.phone}` : ''}
                </p>
                <p className="text-xs text-text-muted mt-0.5">Owner: {r.owner.email}</p>
              </button>
            ))}
          </div>
        )}

        <div className="flex justify-end">
          <Button
            type="button"
            isLoading={linkLoading}
            disabled={!selectedResult}
            onClick={() => void createLink()}
          >
            <Send className="w-4 h-4 mr-2" />
            Request link
          </Button>
        </div>
      </div>

      <div className="rounded-[var(--radius-md)] border border-border/70 p-4 space-y-3">
        <h2 className="text-base font-semibold text-text-primary">Invite owner (not yet subscribed)</h2>
        <Input
          label={`${counterpartLabel} name`}
          value={manualOrganizationName}
          onChange={(e) => setManualOrganizationName(e.target.value)}
        />
        <Input
          label="Owner email"
          type="email"
          value={manualOwnerEmail}
          onChange={(e) => setManualOwnerEmail(e.target.value)}
        />
        <Input
          label="Mobile number (optional)"
          value={manualPhone}
          onChange={(e) => setManualPhone(e.target.value)}
        />
        <div className="flex justify-end">
          <Button
            type="button"
            isLoading={inviteLoading}
            disabled={!manualOrganizationName.trim() || !manualOwnerEmail.trim()}
            onClick={() => void sendInvite()}
          >
            Send invite link
          </Button>
        </div>
      </div>

      <div className="rounded-[var(--radius-md)] border border-border/70">
        <div className="border-b border-border/70 px-4 py-3">
          <h2 className="text-base font-semibold text-text-primary">Requests and invitations</h2>
        </div>
        {loading ? (
          <p className="px-4 py-4 text-sm text-text-secondary">Loading list...</p>
        ) : items.length === 0 ? (
          <p className="px-4 py-4 text-sm text-text-secondary">No records yet.</p>
        ) : (
          <div className="overflow-x-auto">
            <table className="w-full text-sm">
              <thead>
                <tr className="border-b border-border/70 text-left text-text-secondary">
                  <th className="p-3 font-medium">Type</th>
                  <th className="p-3 font-medium">Organization</th>
                  <th className="p-3 font-medium">Owner email</th>
                  <th className="p-3 font-medium">Status</th>
                  <th className="p-3 font-medium">Action</th>
                </tr>
              </thead>
              <tbody>
                {items.map((item) => (
                  <tr key={item.id} className="border-b border-border/40 last:border-0">
                    <td className="p-3 text-text-secondary">
                      {item.kind === 'LINK' ? 'Link request' : 'Invitation'}
                    </td>
                    <td className="p-3 text-text-primary">{item.organizationName}</td>
                    <td className="p-3 text-text-secondary">{item.ownerEmail}</td>
                    <td className="p-3">
                      <span className="inline-flex items-center rounded-full border border-border px-2 py-0.5 text-xs text-text-primary">
                        {item.status}
                      </span>
                    </td>
                    <td className="p-3">
                      {item.kind === 'INVITATION' &&
                        item.status === 'PENDING' &&
                        pendingInviteLinks[item.id]?.invitationUrl && (
                          <Button
                            type="button"
                            variant="outline"
                            size="sm"
                            onClick={async () => {
                              try {
                                await navigator.clipboard.writeText(
                                  pendingInviteLinks[item.id].invitationUrl,
                                );
                                setCopiedId(item.id);
                                setTimeout(() => setCopiedId(null), 1500);
                              } catch {
                                setError('Could not copy invitation link');
                              }
                            }}
                          >
                            {copiedId === item.id ? (
                              <Check className="w-4 h-4" />
                            ) : (
                              <Copy className="w-4 h-4" />
                            )}
                            <span className="ml-1">
                              {copiedId === item.id ? 'Copied' : 'Copy link'}
                            </span>
                          </Button>
                        )}
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        )}
      </div>
    </div>
  );
}
